多态:
同一个对象,在不同时刻表现出现的不同状态。
举例:水(水,冰,水蒸气)
狗(动物,狗)
从代码的角度来看:
编译期状态和运行期状态不一致的现象。
Fu fu = new Fu();
Zi zi = new Zi();
Fu fu = new Zi();
前提:
1:类或者是接口的引用,指向自己的子类对象
2:调用子类重写后的方法
3:有继承或者实现关系。
代码分析:
class Fu {
public int num = 10;
public void show() {
System.out.println("Fu"+num);
}
}
class Zi extends Fu {
public int num = 10;
public int num2 = 20;
public void show() {
System.out.println("Zi"+num);
System.out.println("Zi"+num2);
}
public void method() {
System.out.println("method");
}
}
测试类:
class Test {
public static void main(String[] args) {
/*
Fu f = new Fu();
System.out.println(f.num);
f.show();
Zi zi = new Zi();
System.out.println(zi.num);
zi.show();
*/
//多态
Fu f = new Zi();
System.out.println(f.num);
//System.out.println(f.num2);
f.show();
//f.method();
}
}
多态中成员的特点:
成员变量:编译和运行都看左边。
成员方法:编译看左边,运行看右边。
为什么?
因为方法有重写,而变量没有。
经典案例:
/*
设计电脑主板和接口
主板类
接口USB
外接设备
*/
//定义主板类,开机功能,使用USB接口设备的功能
class MainBoard{
public void open(){
System.out.println("主板开机");
}
//重点关注使用的USB接口设备
public void useUSB(USB u){// USB u = new Upan();
u.read();
u.write();
}
}
//定义USB的接口,规定接口规范,2个方法,读和写
interface USB{
public abstract void read();
public abstract void write();
}
//定义U盘类,必须符合USB接口规则
class Upan implements USB{
public void read(){
System.out.println("读取U盘数据");
}
public void write(){
System.out.println("向U盘写数据");
}
}
//定义网卡类,必须符合USB接口规则
class NetCard implements USB{
public void read(){
System.out.println("读取网卡数据");
}
public void write(){
System.out.println("向网卡写数据");
}
}
class PersonComputer{
public static void main(String[] args) {
//建立主板对象
MainBoard mb = new MainBoard();
mb.open();
//将U盘,连接到USB接口,调用主板的使用usb这个方法,传递U盘对象
mb.useUSB(new Upan());
//将U盘,连接到USB接口,调用主板的使用usb这个方法,传递网卡对象
mb.useUSB(new NetCard());
}
}
/*
外接设备,并没有直接和主板连接
外接设备,直接到了USB接口上,接口和主板连接
USB接口出现后,不但提供了规则,降低了外接设备和主板的耦合性
耦合性降低,程序的扩展性提高
*/
Object类:
所有类爹地,所有类继承Object
toString()方法:获取到对象的地址值
重写toString()方法,建立对象自己的字符串表现形式
格式: return "类名" + 所有的成员变量的... + ... + ;
equals()方法:用来进行对象之间的比较,任何对象都具备比较性
A: 不覆盖的时候,默认比较对象的真实地址引用
B: 覆盖equals方法,建立自定义的比较形式,用来比较类中成员变量的值
代码解析:
/*
Object
public String toString()
在输出语句中sop()
打印的是一个引用类型。默认调用对象中的toString()方法
System.out.println(p)==System.out.println(p.toString())
public boolean equals(Object obj)
*/
class Person{
String name;
int age;
Person(String name,int age){
this.age = age;
this.name = name;
}
// 覆盖对象中的toString方法
public String toString(){
// 依据:返回 类名 和 类中成员变量的值
return "Person " + name + "..." + age ;
}
//覆盖对象中的equals()方法
public boolean equals(Object obj){
//return this == obj;
//对obj进行健壮性判断
//如果this,和参数obj,指向的是同一个对象,一个对象没有可比性
if(this == obj);
return true;
if( obj == null);
return false;
//obj.age p2对象提升为了Object类型,类型转换
if(obj instanceof Person){
Person p = (Person)obj;
return this.age == p.age;
}
//传递的参数,不是人类型,没有可比性
return false;
}
}
class ObjectDemo {
public static void main(String[] args) {
Person p1 = new Person("haha",18);
Person p2 = new Person("xixi",19);
System.out.println(p1);//Person@67f6dc61--哈希值,理解为内存地址
System.out.println(p2);//Person@67f6dc61--哈希值,理解为内存地址
boolean b = p1.equals(p2);
System.out.println(b);
}
}
内部类:
将一个类定义在另一个类的里面,对里面那个类就称为内部类(内置类,嵌套 类)。
访问特点:
1:内部类可以直接访问外部类中的成员,包括私有成员。
2:而外部类要访问内部类中的成员必须要建立内部类的对象。
定义时的特点:
内部类定义在成员位置上:
可以被private static成员修饰符修饰。
被static修饰的内部类只能访问外部类中的静态成员。
内部类定义在局部位置上:
可以直接访问外部类中的成员。
同时可以访问所在局部中的局部变量,但必须是被final修饰的。