多态
1. 多态:
多种形态。
指父类引用指向不同的子类对象,由于子类对象的不同,产生不同的行为。
2. 多态的类型:
① 向上转型:父类引用指向子类对象,而程序没有报错的现象,称为向上转型。
里氏代换:任何基类可以出现的地方,子类一定可以出现
② 向下转型
3. 作用:
提高代码的扩展性。
提高代码的复用性。
代码:
package exec;
public class topic01 {
public static void main(String[] args) {
Lamp lamp = new Lamp();
Bulb redBulb = new RedBulb();
Bulb greenBulb = new GreenBulb();
lamp.on(greenBulb);
lamp.on(redBulb);
}
}
/*1.设计一个台灯类Lamp其中台灯有灯泡这个属性,还有开灯(on)这个方法,
设计一个灯泡类 其中有红灯泡(RedBulb) 和绿灯泡(GreenBulb)
他们都有一个发亮的方法,请设计出一段代码可以使台灯开启灯泡发亮,
并且保证替换不同种类的灯泡台灯类代码不被修改*/
class Lamp{
Bulb b;
public void on(Bulb b) {
b.f();
}
}
class Bulb{
public void f() {
}
}
class RedBulb extends Bulb{
@Override
public void f() {
System.out.println("红灯泡发亮");
}
}
class GreenBulb extends Bulb{
@Override
public void f() {
System.out.println("绿灯泡发亮");
}
}
输出结果:
向上转型的前提
1. 数据赋值 同种类型的变量= 同种类型的值
2. 前提:
① 具有继承关系的子父类。
② 必须要有方法的重写。
③ 父类引用指向子类对象。
向上转型的弊端
1. 发生了向上转型的父类引用,只能调用属于父类的属性和子类重写父类的方法,不能调用子类特有的属性和方法。
2. 为了 解决上面的弊端,就需要向下转型。
3. 向下转型:
格式:
(要转换的类型) 要转换的父类引用
向下转型的弊端
1. 可能会发生类型转换异常。
ClassCastException
2. 当父类引用中的子类对象,在向下转型过程中,如果转换的不是同种子类数据类型,就会报该异常。
3. 为了避免类型转换异常的发生,可以通过判断来解决。
1》 instanceof
格式:
要转换数据类型的对象 instanceof 要转换的类型
返回值是boolean类型,如果返回true表示是该类型,false表示不是。
注意:
要转换的类型,必须精确,与要进行强制类型转换的数据类型必须一致。
代码示例:
boolean flag=a instanceof Cat1;
多态之间的成员调用
1. 绑定:将一个方法的调用同一个方法主体关联起来被称为绑定。
2. 绑定的分类:
2.1 编译期绑定:静态绑定
在编译的时候,确定。
属于编译期绑定:
1> 属性:无论是静态还是非静态属性。
2>静态方法。
2.2 运行期绑定:动态绑定
在运行时,才确定到底执行那个方法,如果是子类,会到子类中去寻找有没有重写的方法,如果有执行重写的方法。
属于运行期绑定:
1>非静态方法。
总结:
对于 属性或静态方法,只要看他们的数据类型就可以。
非静态方法,除了要看对象的数据类型还要看真实对象,如果是子类对象就执行子类重写父类的方法。
package a;
/*
1. 编译看左边,运行看右边。
2. 编译的时候要看=左边的引用所属的类型中,是否有该方法的定义,
如果有就编译成功,如果没有就编译失败。
3. 运行的时候,要看=右边的对象所属的类型,是如何实现这个方法的。
最终运行的是子类重写过的方法实现。*/
public class 绑定 {
public static void main(String[] args) {
A a=new A();
ZiA zia=new ZiA();
System.out.println(a.a+":"+zia.a);
A ziaz=new ZiA();//向上转型
System.out.println(ziaz.a);
System.out.println(ziaz.b);
System.out.println(zia.b);
a.fun();
ziaz.sf();
ziaz.sf();
a.sf();
a.fun();
zia.fun();
ziaz.fun();
}
}
class A{
int a=10;
static int b=18;
public void fun() {
System.out.println("这是A中的一个非静态方法。");
}
public static void sf() {
System.out.println("这是A中的一个静态方法。");
}
}
class ZiA extends A{
int a=20;
static int b=39;
public void fun() {
System.out.println("这是ZiA类中的一个非静态方法。");
}
public static void sf() {
System.out.println("这是ZiA中的一个静态方法。");
}
}
输出结果为: