多态的定义:在有继承和子类重写的前提下,将父类对象的引用指向子类对象。
示例:
class Father {}
class Son extends Father {}
Father fa = new Son();
多态的理解:编译看左边,运行看右边。
在代码编译时,表现的是父类特征,运行时表现的是子类的特征。
多态的好处:
- 增加代码的复用,减少冗余。
- 降低类与类之间的耦合。
多态的应用:
-
在形参
class Animal {
public void walk() {
sysout(“动物走路”);
}public void eat() {
sysout(“动物吃东西”)
}
}
class Cat extends {
public void eat() {
sysout(“猫吃饭”)
}
}
public Person {
public static void main(String args[]) {
showAnimal(new Cat())
}
public static void showAnimal(Animal an) {
an.eat();
}
}
-
在数组
public AnimalTest {
public static void main(Strings arg[]) {
Animal [] animals = new Animal[3];
animals[0] = new Cat();
animals[1] = new Cat();
animals[2] = new Dog();for(int i = 0; i < animals.length; i++) { animals[i].eat(); }
}
} -
多态应用在返回值
方法的返回值类型声明为父类的类型,实际返回值是子类对象
public class Test03 {
public static void main(String[] args) {
Animal c = buy(“猫咪”);
System.out.println(c.getClass());
c.eat();
}
/*- 设计一个方法,可以购买各种动物的对象,此时不确定是那种具体的动物
- 返回值类型是父类的对象
- 多态体现在 返回值类型 Animal ,实际返回的对象是子类的new Cat(),或new Dog()
*/
public static Animal buy(String name){
if(“猫咪”.equals(name)){
return new Cat();
}else if(“小狗”.equals(name)){
return new Dog();
}
return null;
}
}
多态引用时关于成员变量与成员方法引用的原则:
- 成员变量:只看编译时左边类型,即编译看左边,运行也看左边;
- 非虚方法:static、final修饰的方法,构造器都是不会被改变的,因为这三类都是不能被重写;
- 虚方法:在Java中虚方法是指在编译阶段和类加载阶段都不能确定方法的调用入口地址,在运行阶段才能确定的方法,即可能被重写的方法。
当我们通过“对象.方法”的形式,调用一个虚方法,我们要如何确定它具体执行哪个方法呢?
静态分派:先看这个对象的编译时类型,在这个对象的编译时类型中找到最匹配的方法, 最匹配的是指, 实参的编译时类型与形参的类型最匹配
动态绑定:再看这个对象的运行时类型,如果这个对象的运行时类重写了刚刚找到的那个最匹配的方法,那么执行重写的,否则仍然执行刚才编译时类型中的那个方法