对象转型
学习多态前先明白一个叫对象转型的概念,如:
1 class Animal{ 2 void sleep(){ 3 System.out.println("睡觉"); 4 } 5 } 6 7 class Cat extends Animal{ 8 void catchMouse(){ 9 System.out.println("捕鼠"); 10 } 11 } 12 13 class Dog extends Animal{ 14 15 } 16 17 public class Test { 18 19 public static void main(String[] args) { 20 Animal a = new Cat(); //向上转型 21 Cat c = (Cat) a; //向下转型 22 c.catchMouse(); 23 // Dog d = (Dog) a; 运行时会报错,a实际是Cat,不能转成Dog,两者没有关系 24 System.out.println(a instanceof Animal); 25 } 26 27 }
Cat向上转型之后,视为Animal类,只能访问到父类中的成员,而不能访问Cat中的成员,如需访问,需再次强制转向下转换成Cat类,使用多态过程中,一般都默认会涉及到对象转型。
多态概述
多态体现在父类引用指向子类对象。实现多态的前提是:1.类与类之间存在关系,可以是继承关系或者是实现关系;2.而且子类中必须要有方法的重写;3.有父类或者父类接口引用指向子类对象。代码示例:
1 class Animal{ 2 void sing(){ 3 System.out.println("唱歌"); 4 } 5 } 6 7 class Cat extends Animal{ 8 void sing(){ 9 System.out.println("喵喵"); 10 } 11 } 12 13 class Dog extends Animal{ 14 void sing(){ 15 System.out.println("汪汪"); 16 } 17 } 18 19 public class Test { 20 21 public static void main(String[] args) { 22 Cat c = new Cat(); 23 function(c); 24 // Dog d = new Dog(); 25 // function(d); 26 } 27 28 public static void function(Animal a){ //相当于Animal a = new Cat()对象转型 29 a.sing(); 30 } 31 32 }
这段代码最终运行输出的是:喵喵。主函数中创建了一个c对象,并调用function方法,很明显function方法中参数为Animal a,由于Cat继承了Animal,没有问题,可是最终输出为什么不是Animal中的方法唱歌,这是由多态成员方法的特点来决定的。
1.编译期间:参阅的是引用型变量所属的类中是否有调用的方法,很明显这里的Animal是有方法的sing的;
2.运行期间:参阅对象所属的类中是否有调用方法,很明显这里的Cat中也是有sing方法的;
所以最终运行出来的是Cat中的方法。也就是说子类中必须要有重写,才是多态。
多态的分类
1.具体类多态,如:
1 class Fu{] 2 3 class Zi extends Fu {} 4 5 Fu f = new Zi();
2.抽象类多态,如:
abstract class Fu {} class Zi extends Fu {} Fu f = new Zi();
3.接口多态,如:
interface Fu{} class Zi implements Fu{} Fu f = new zi();
多态中的成员访问特点
1.对于成员变量:编译看左边,运行看左边。(即编译的时候检查父类中是否存在该变量名,运行的时候访问的也是父类中该变量的值)
2.对于构造方法:子类的构造都会默认访问父类构造。
3.对于成员方法:编译看左边,运行看右边。
4.对于静态方法:编译看左边,运行看右边。