一、关于多态性
在面向对象的程序设计语言中,多态是继数据抽象和继承之后的第三种基本特征。
多态是同一个行为具有多个不同表现形式或形态的能力。
多态就是同一个接口,使用不同的实例而执行不同操作。
1、何为多态:父类的引用指向子类的对象(或子类的对象赋给父类的引用)
2、多态前提
①类的继承关系
②方法的重写
3、多态的使用:虚拟方法调用
有了对象的多态性以后,我们在编译期,只能调用父类中声明的方法,但在运行期,我们实际执行的是子类重写父类的方法。
即**“编译看左边,运行看右边”**(只适用于方法)
二、虚拟方法调用
e.g.
public class Person {
String name;
int age;
public void walk(){
System.out.println("People can walk.");
}
}
class Woman extends Person{
@Override
public void walk() {
System.out.println("Woman usually walk slowly");
}
public void shopping() {
System.out.println("Woman likes shopping");
}
}
class Man extends Person{
@Override
public void walk() {
System.out.println("Man usually walk quickly");
}
public void fitness() {
System.out.println("Man enjoy fitness");
}
}
- 正常方法使用
Person person = new Person();
person.walk();
Man man = new Man();
Man.walk();
- 多态情况下使用
子类中定义了与父类同名同参数的方法,在多态情况下,将此父类的方法成为“虚拟方法”,父类根据赋给它的不同子类对象,动态调用属于子类的该方法。这样的方法调用在编译期是无法确定的
Person e = new Man();
e.walk(); //调用Student类的getInfo()方法
- 编译时类型和运行时类型
编译时e为Person类型,而方法的调用是在运行时确定的,所以调用的是Student类的getInfo()方法,称为动态绑定
有了对象的多态性以后,内存中实际上是加载了子类特有的属性和方法,但是由于变量声明为父类类型,导致编译时,只能调用父类中声明的属性和方法。子类特有的属性和方法不能调用。
如何才能调用子类特有的属性和方法?
向下转型:使用强制类型转换符
向上转型:多态
向下转型:使用instanceof进行判断
三、instanceof操作符
x instanof A : 检查x是否为类A的对象,返回值为boolean型
①要求x所属类与类A必须是子类和父类的关系,否则编译错误
②如果属于类A的子类B,x instanceof A值也为true
public void test1(Person e){
if(e instanceof Person)
//处理Person类及其子类对象
if(e instanceof Woman)
//处理Woman类及其子类对象
if(e instanceof Man)
//处理Man类及其子类对象
}
e.g.
public void test2(Person e) {
if(e instanceof Woman) {
Woman woman = (Woman)e;
woman.shopping();
}
if(e instanceof Man) {
Man man = (Man)e;
man.fitness();
}
}