多态是方法的多态,属性没有多态。
一、Java的多态分运行多态和编译多态
- 编译多态:
编译多态 通常指的是方法的重载,方法在编译时由程序根据参数列表的不同选择相应的方法。
- 运行多态
运行多态 指的程序编译时无法确定引用变量调用的是哪个实例的具体方法,最终调用状态只有在程序执行过程中才被会被决定,这种动态调用子父类方法的情况就是Java的多态 。
注意:多态必须是继承关系,(父类和子类),没联系抛出类型转换异常:ClassCastException
。
二、多态的存在条件:
- 必须有继承关系
- 子类重写了父类的方法,没有重写就没有多态
- 程序中存在父类引用指向子类对象的情况。 SuperClass = s1 = new SubClass() ;
三、多态实例:
//1. Animal 父类
package com.zctou.oop.demo07;
public class Animal {
public void run() {
System.out.println("动物在跑!");
}
}
//2. Dog 子类
package com.zctou.oop.demo07;
public class Dog extends Animal{
@Override
public void run() {
System.out.println("狗在跑!");
}
public void dogEat(){
System.out.println("狗在吃~");
}
}
//3. Application 测试类
package com.zctou.oop;
import com.zctou.oop.demo07.Dog;
import com.zctou.oop.demo07.Animal;
public class Application {
public static void main(String[] args) {
//new Dog()对象的类型是确定的
//Dog dog,Animal animal,Object o,引用变量的类型是不确定的,可以是对像的父类及父类有关系的类
Dog dog = new Dog();
Animal animal = new Dog();
Object o = new Dog();
dog.run();
dog.dogEat();
animal.run();
//animal.dogEat();
}
}
//4. 输出
狗在跑!// dog.run(),子类调用自身方法
狗在吃~ //dog.dogEat();子类调用自身独有方法
狗在跑!// animal.run();父类调用的是被子类重写过的方法,多态出现
如果父类强行调用子类的特有方法,编译不通过,报错误为:找不到符号。
这里涉及类型转换的问题,父类调用子类特有方法,要强转成子类的类型。如上面例子:
//animal.doEat(); 要把animal强制转换成Dog类型
((Dog) animal).dogEat();
可以看到:当new一个对象的时候,对象的型就是确定的。而引用这个对象的变量的类型是不确定的,可能是对象本身的类型,也有可能是其他父类的类型。
也就是
=
左边的类型不确定,而=
右边的类型是确定的,这也是多态的前提。引用变量能调用的方法是看
=
左边的类型,与=
右边关系不大。右边的子类重写了左边的方法,则调用右边子类的重写方法,其他 一概调用左边父类的方法。