您的位置:首页 > 职场人生

黑马程序员————学习日记【6】 【Java面向对象2】

2013-04-09 19:29 633 查看
------- android培训java培训、期待与您交流! ----------
 



/*
将学生和工人的共性描述提取出来,单独进行描述。
只要让学生和工人与单独描述的这个类有关系,就可以了。

继承:
1、提高了代码的复用性
2、让类与类之间产生了关系。有了这个关系,才有了多态的特性。

注意:千万不要为了获取其他类的功能,简化代码而继承。
必须是类与类之间有所属关系才可以继承。所属关系是 is a。

备注:判断类与类之间是否有所属关系的方式:
那就先继承一下,继承完成后,子类应该具备父类中的内容,
那么就看一下父类中的内容是不是子类都应该具备,如父类
中有的功能不是子类该具备的,那么它们之间就不应有继承。
*/

/*
class C
{
void demo1(){}
}

class A extends C
{
//void demo1(){}
void demo2(){}
}

class B extends C
{
//void demo1(){}
void demo3(){}
}

*/
//Java语言中:java只支持单继承,不支持多继承。
//多继承是一个类可以继承多个类。多继承容易带来安全隐患。
//即Student类能继承Person类,就不能继承其他类了。
//当多个父类中定义了相同功能,当功能内容不同时,子类对象
//不确定要运行哪一个。

//但是java保留了多继承机制,并用另一种体现形式来完成,多实现。

//java支持多层继承。也就是一个继承体系。
//如何使用一个继承体系中的功能呢?
//想要使用体系,先查阅体系中父类的描述。因为父类中定义的是该体
//系中的共性功能。通过了解共性功能,就可以知道该体系的基本功能。
//那么这个体系已经可以基本使用了。
//那么在具体调用时,要创建最子类的对象,为什么呢?
//一是因为有可能父类不能创建对象,如抽象类和接口。
//二是创建子类对象可以使用更多的功能。包括基本的也包括特有的。

//简单一句话:查阅父类功能,创建子类对象使用功能。
//日后在查阅java的体系结构的时候,就按照这种方法来思考。

//单继承和多继承怎么去区分?
//记住:java中一个孩子只能有一个父亲,不允许有多个父亲。

/*
聚集:has a
谁是谁的一种,那叫继承;谁里面有谁,那叫聚集。
分为聚合和组合两种,它们的紧密联系程度稍有不同。

聚合:球员与球队的关系就是聚合关系。
即球员是球队中的一个,球队中有球员。
组合:事物的联系程度更紧密。
手、脚都是人身体的一部分。
与球员比,手和脚对身体的重要程度要比球员对球队高。

写继承的目的,在于描述现实生活中的事物。
有时候,用聚集的次数要比继承还要多一些。
*/

class Person
{
String name;
int age;
}
class Student extends Person
{
void study()
{
System.out.println("good study");
}
}

class Worker extends Person
{
void work()
{
System.out.println("good work");
}
}
class  ExtendsDemo
{
public static void main(String[] args)
{
Student s = new Student();
s.name = "zhangsan";
}
}


 
/*
子父类出现后,类成员的特点:

类中成员:
1、变量
2、函数
3、构造函数

1、变量
如果子类中出现非私有的同名成员变量时,
子类要访问本类中的变量,用this
子类要访问父类中的同名变量,用super

super的使用和this的使用几乎一致
this代表的是本类对象的引用
super代表的是父类对象的引用
*/
class Fu
{
int num = 4;
}

class Zi extends Fu
{
//	int num = 5;
void show()
{
System.out.println(num);
}
}

class ExtendsDemo2
{
public static void main(String[] args)
{
Zi z = new Zi();
z.show();
//		System.out.println(z.num+"...."+z.num);
}
}

 
/*
2、子父类中的函数

当子类出现和父类一模一样的函数时,
当子类对象调用该函数,会运行子类函数的内容。
如同父类的函数被覆盖一样。

这种情况是函数的另一个特性:重写(覆盖)

父类的方法还在内存当中,没有运行而已。

当子类继承了父类,沿袭了父类的功能到子类中,
但是子类虽具备该功能,但是功能的内容却和父类
不一致,此时没有必要定义新功能,而是使用覆盖特性,
保留父类的功能定义,并重写功能内容。

覆盖注意事项:
1、子类覆盖父类,必须保证子类权限大于等于父类权限,
才可以覆盖,否则编译失败。

2、静态只能覆盖静态。

记住:
重载:只看同名函数的参数列表
重写:子父类要一模一样,包括返回值类型。

特殊情况:在多态中,父类方法的返回值类型和子类方法
的返回值类型是可以有不同的。但是,这两个
参数类型得有关系才行,待续。
*/

class Fu
{
int show()
{
System.out.println("fu show");return 1;
}
void speak()
{
System.out.println("vb");
}
}

class Zi extends Fu
{
void speak()
{
System.out.println("java");
}
void show()
{
System.out.println("zi show");
}
}
class ExtendsDemo3
{
public static void main(String[] args)
{
Zi z = new Zi();
z.speak();
}
}

class Tel
{
void show()
{
System.out.println("number");
}
}

class NewTel extends Tel
{
void show()
{
//		System.out.println("number");
super.show();
System.out.println("name");
System.out.println("pic");
}
}

 
/*
3、子父类中的构造函数

问:构造函数可以覆盖吗?
答:不能,覆盖得一模一样才行,子父类构造函数不能
一模一样。因为构造函数是随着类名走的,子父类
类名不能一致。

在对子类对象进行初始化时,父类的构造函数也会运行,
那是因为子类的构造函数在默认的第一行有一条隐饰的
语句super();

super(); 会访问父类中空参数的构造函数。而且子类
中所有的构造函数默认第一行都是super();

为什么子类一定要访问父类中的构造函数?

因为父类中的数据子类可以直接获取。所以子类对象
在建立时,需要先查看父类是如何对这些数据进行初始
化的。所以子类在对象初始化时,要先访问一下父类中
的构造函数。如果要访问父类中指定的构造函数,可以
通过手动定义super语句的方式来指定。

注意:super语句一定定义在子类构造函数的第一行
*/
//子类的实例化过程
/*
结论:
子类的所有的构造函数,默认都会访问父类中空参数的
构造函数。因为子类每一个构造函数内的第一行都有一
句隐饰super();

当父类中没有空参数的构造函数时,子类必须手动通过
super语句形式来指定访问父类中的构造函数。

当然:子类的构造函数第一行也可以手动指定this语句
来访问本类中的构造函数,子类中至少会有一个构造函数
会访问父类中的构造函数。

*/
class Fu //extends Object
{
int num;
Fu()
{
//super();
num = 60;
System.out.println("fu run");
}
Fu(int x)
{
System.out.println("fu...."+x);
}
}

class Zi extends Fu
{
Zi()
{
//super();
//super(4);
System.out.println("zi run");
}
Zi(int x)
{
this();
//super();
//super(2);
System.out.println("zi..."+x);
}
}
class  ExtendsDemo4
{
public static void main(String[] args)
{
Zi z = new Zi();
System.out.println(z.num);
}
}

class Person
{
private String name;
Person(String name)
{
this.name = name;
}

void show(){}
}
class Student extends Person
{
Student(String name)
{
super(name);
}
void method()
{
super.show();
}
}




 
/*
final:最终。作为一个修饰符。
1、可以修饰类,函数,变量。
2、被final修饰的类不可以被继承。
为了避免被继承,被子类复写功能。
用final类,它不能有子类继承。

继承有一个弊端:它打破了封装性。

3、被final修饰的方法不可以被复写

4、被final修饰的变量是一个常量,只能
赋值一次,既可以修饰成员变量,又
可以修饰局部变量。

当在描述事物时,一些数据的出现 值是固定的,
那么此时为了增强阅读性,都给这些值起个名字,
方便阅读,而此值不需要改变,所以加final修饰

作为常量:常量的书写规范所有字母都大写,如果
由多个单词组成,单词间通过-连接。

以后,凡是在写代码的时候,出现了一些固定数据,
这些值不会变化,即使只出现了一次,也建议把此
数据起个名字,那样阅读性更好。前提是,数据不
能变,变了就是变量了。

而如果值不变化,并且在成员位置上,常常还加上
一个修饰符static。因为数据是固定的,不改了,
那就共享了,共享数据加static就可以了。如再加
上public ,此数据的权限就足够大了,就不用对象
访问了,类名就可以访问了。因为它static了,此
时public static final也可以称为全局常量。

5、内部类定义在类中的局部位置上时,只能访问该
局部被final修饰的局部变量。

备注:一旦看到final,
1、名称会有变化,大小写要区分,全都是大写
2、数据固定的时候写PI,起名字为了增强阅读性

写代码阅读性很重要

现在学类的时候有两个修饰符,public和final。
private是修饰成员的。

*/
public class Demo
{
final int x = 3;
public static final double PI = 3.14;
final void show1()
{}
void show2()
{
final int y = 4;
System.out.println(3.14);
}
}
class SubDemo extends Demo
{
//	void show1(){}
}
class FinalDemo
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}

/*
假如在开发一个系统时需要对员工进行建模,员工包含
三个属性:姓名,工号及工资。经理也是员工,除了含
有员工的属性外,另外还有一个奖金属性。请使用继承
的思想设计出员工类和经理类。要求类中提供必要的方
法进行属性访问。

员工类:name id  pay
经理类:继承了员工,并有自己特有的bonus(奖金)
*/

class Employee//Employee此时是普通员工和经理向上
//抽取出来的东西
{
private String name;
private String id;
private double pay;

Employee(String name,String id,double pay)
{
this.name = name;
this.id = id;
this.pay = pay;
}
public abstract void work();
}

class Manager extends Employee
{
private int bonus;
Manager(String name,String id,double pay,int bonus)
{
super(name,id,pay);
this.bonus = bonus;
}
public void work()
{
System.out.println("manager work");
}
}

class pro extends Employee//professional 专业人士
{
Pro(String name,String id,double pay)
{
super(name,id,pay);
}
public void work()
{
System.out.println("pro work");
}
}
class AbstractTest
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}

//Employee此时是普通员工和经理向上抽取出来的东西,
//经理和员工之间本身不具备继承关系,谁也不是谁的
//一种,他们都属于打工的人。打工的人具备什么属性
//,他们就具备什么属性。

/*
需求:获取一段程序运行的时间
原理:获取程序开始和结束的时间并相减即可

获取时间:System.currentTimeMillis();

当代码完成优化后,就可以解决这类问题。

这种方式,叫做模板方法设计模式。

什么是模板方法?
在定义功能时,功能的一部分是确定的,一部分是不确定的,而确定的部分在使用不确定的部分,
那么这时就将不确定的部分暴露出去,由该类的子类去完成。

这种设计模式提高了扩展性,也提高了复用性。
*/

abstract class GetTime
{
public final void getTime()
{
long start = System.currentTimeMillis();

runcode();

long end = System.currentTimeMillis();

System.out.println("毫秒:"+(end-start));
}
public abstract void runcode();
}

class SubTime extends GetTime
{
public void runcode()
{
long start = System.currentTimeMillis();

for(int x=0; x<4000;x++)
{
System.out.print(x);
}
}
}
class TemplateDemo
{
public static void main(String[] args)
{
// GetTime gt = new GetTime();
SubTime gt = new SubTime();
gt.getTime();
}
}



class Fu
{
static int num = 5;
void method1()
{
System.out.println("fu method_1");
}
void method2()
{
System.out.println("fu method_2");
}
static void method4()
{
System.out.println("fu method_4");
}
}

class Zi extends Fu
{
static int num = 8;
void method1()
{
System.out.println("zi method_1");
}
void method3()
{
System.out.println("zi method_3");
}
static void method4()
{
System.out.println("zi method_4");
}
}
class  DuoTaiDemo4
{
public static void main(String[] args)
{
//		Fu f = new Zi();
//		System.out.println(f.num);
//
//		Zi z = new Zi();
//		System.out.println(z.num);

//		f.method1();
//		f.method2();
//		f.method3();

Fu f = new Zi();
System.out.println(f.num);
f.method4();

Zi z = new Zi();
z.method4();

/*
在多态中,成员变量的特点:
无论编译和运行,都参考左边(引用型变量所属的类)。

在多态中,静态成员函数的特点:
无论编译和运行,都参考左边。

在多态中成员函数(非静态)的特点:
在编译时期:参阅引用型变量所属的类中是否有调用的方法。
如果有,编译通过;如果没有,编译失败。

在运行时期:参阅对象所属的类中是否有调用的方法。

简单总结:成员函数在多态调用时,编译看左边,运行看右边。
*/

//		Zi z = new Zi();
//		z.method1();
//		z.method2();
//		z.method3();
}
}
/*
问:父类和子类,有相同名称的成员变量,这两个变量也是
静态的,那么多态时,调用的打印结果是父的还是子的?

答:父的
*/


/*
需求:
电脑运行实例,
电脑运行基于主板。
*/
interface PCI
{
public void open();
public void close();
}

class MainBoard
{
public void run()
{
System.out.println("mainboard run");
}
public void usePCI(PCI p)//PCI p = new NetCard();
{						//接口型引用指向自己的子类对象。
if(p!=null)
{
p.open();
p.close();
}

}
}

class NetCard implements PCI
{
public void open()
{
System.out.println("netcard open");
}
public void close()
{
System.out.println("netcard close");
}
}

class SoundCard implements PCI
{
public void open()
{
System.out.println("SoundCard open");
}
public void close()
{
System.out.println("SoundCard close");
}
}

/*
class MainBoard
{
public void run()
{
System.out.println("mainboard run");
}
public void useNetCard(NetCard c)
{
c.open();
c.close();
}
}

class NetCard
{
public void open()
{
System.out.println("netcard open");
}
public void close()
{
System.out.println("netcard close");
}
}
*/
class	DuoTaiDemo
{
public static void main(String[] args)
{
MainBoard mb = new MainBoard();
mb.run();
mb.usePCI(null);
mb.usePCI(new NetCard());
mb.usePCI(new SoundCard());
}
}


 

/*
需求:数据库的操作
数据是:用户信息

1、连接数据库JDBC  Hibernate
2、操作数据库
c create   r  read    u upate    d  delete
3、关闭数据库连接
*/

interface UseInfoDao
{
public void add(User user);

public void delete(User user);
}
class UserInfoByJDBC  implements UserInofDao
{
public void add(User user)
{
1、JDBC连接数据库
2、使用sql添加语句添加数据
3、关闭连接
}
public void delete(User user)
{
1、JDBC连接数据库
2、使用sql添加语句删除数据
3、关闭连接
}
}

class UserInfoByHibernate implements UserInfoDao
{
public void add(User user)
{
1、Hibernate连接数据库
2、使用sql添加语句添加数据
3、关闭连接
}
public void delete(User user)
{
1、Hibernate连接数据库
2、使用sql添加语句删除数据
3、关闭连接
}
}
class DBOperate
{
public static void main(String[] args)
{
//		UserInfoByJDBC ui = new UserInfoByJDBC();
//		UserInfoByHibernate ui = new UserInfoByHibernate();
UserInfoDao ui= new UserInfoByJDBC();
ui.add(user);
ui.delete(user);
}
}


/*
Object:是所有对象的直接或者间接父类,传说中的上帝。
该类中定义的肯定是所有对象都具备的功能

Object类中已经提供了对 对象是否相同的比较方法
如果自定义类中也有比较相同的功能,没有必要重新定义
只要沿袭父类中的功能,建立自己特有比较内容即可。
这就是覆盖。
*/
class Demo //extends Object
{
private int num;
Demo(int num)
{
this.num = num;
}
public boolean equals(Object obj)//Object obj = new Demo();
{
if(!(obj instanceof Demo))
return false;
Demo d = (Demo)obj;
return this.num == d.num;
}
/*
public boolean compare(Demo d)
{
return this.num==d.num;
}
*/
public String toString()
{
return "demo:"+num;
}
}
class Person
{
}

class  ObjectDemo
{
public static void main(String[] args)
{
Demo d1 = new Demo(4);
System.out.println(d1.toString());
Demo d2 = new Demo(7);
System.out.println(d2.toString());
//		Demo d2 = new Demo(5);
//		Class c = d1.getClass();
//
//		System.out.println(c.getName());

//		System.out.println(c.getName()+"@@"+Integer.toHexString(d1.hashCode()));
//		Person p = new Person();
//		System.out.println(d1.equals(p));

}
}


 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: