一、前提
继承+重写 +父类引用指向子类对象。
ps:当使用父类引用指向子类对象的时候,只能使用子类中的延续方法和重写方法。如果要使用新增方法必须进行强转。例如:
QQ是Car的子类
Car car =new QQ();
QQ qq =(QQ)car;//只有这样才能调用QQ类的新增方法
二、多肽的常见方式
1、返回类型使用父类型
例如:简单工厂模式
2、形式使用父类型
public static void test(Car car)
使用这种方法签名,调用的时候可以传各种车的子类
三、属性不能多肽
Car car = new QQ();
打印car.type 结果是car。这说明属性不能多态
调用car.run()方法,输出的结果是QQ光脚的不怕穿鞋的。这里发生了多肽,并且方法对于属性的选择遵循就近原则。如:QQ的run方法选择了离他近的type
例2:
class Sub extends Base{public static final String FOO = "bar";}
public class Base{
public static final String FOO = "foo";
}
//s = Sub
System.out.print(((Base)s).FOO);
运行结果是foo,因为s被强转成了父类,只能打印父类的属性
四、类型转化
1、关系
1)、父类是父类
2)、子类是子类
3)、子类是父类
4)、父类不是子类
5)、子类不是其他子类
2、自动类型转化
父类 = 子类,即:父类引用指向子类的时候发生总动类型转化
3、强制类型转化
小类型变量 =(小类型)大类型值 ps:小类型是子类,大类型是父类
ps:要注意下面的这种错误
Bmw和QQ都是Car的子类
qq2 =(QQ)((Car)bmw);
上面的代码过得了编译,但会发生运行错误,抛出ClassCastException
4、使用instanceof关键字,避免ClassCastException
1)使用方法:引用 instanceof 类名
如果引用指向的对象是与类名同辈或者是类名的儿子、孙子等直系亲属则返回true,否则返回false.
如果引用(不是引用指向的类)和类名不在同一条继承链上,则会出现编译错误
五、一点题外话
equals:默认比较地址,需要比较内容 对其重写