1.首先Java中的多态实现过程有三步
- 类与类之间出现继承关系
- 子类重写父类的方法
- 在调用成员方法的时候,用父类引用去指向子类实例对象
首先编写一个父类Animal
public class Animal {
public String a = "123AAA";
public void eat(){
System.out.println("父类吃饭");
}
}
其次编写两个子类继承该父类
public class Cat extends Animal{
public String a = "123";
@Override
public void eat() {
System.out.println("小猫吃饭");
}
}
public class Dog extends Animal{
public String a = "123";
@Override
public void eat() {
System.out.println("狗类吃饭");
}
}
再编写一个动物执行方法类
public class AnimalEat {
public void animalEat(Animal animal){
animal.eat();
System.out.println(animal.a);
}
}
Animal animal = new cat(); 左边为形参 右边为实参(后文提到)
等到Dog,Cat 对象传入进来的时候 由于对象是引用类型的数据,所以传进来的是其在堆内存的内存地址(被存放在栈内存)animal.eat();所以在调用成员方法的时候 编译看左边,执行看右边,编译的时候看的是animal也就是父类的引用,父类Animal中有eat(被子类Cat,Dog重写)的成员方法,所以编译不会报错,而在执行过程中由于父类的引用实际为栈空间里面的一串字符(内存地址),eat方法是引用类型的,在堆空间里面,所以要根据内存地址引用到真正的空间即右边的new cat(),所以是执行看右边如果是访问成员变量(值类型数据)
编译看左边,执行还是看左边,由于访问值类型数据是存放在栈中,而左边的父类引用同时也是在栈中,编译和执行都根据左边(自己理解)
测试类
public class Test {
public static void main(String[] args) {
AnimalEat animalEat = new AnimalEat();
animalEat.animalEat(new Dog());
animalEat.animalEat(new Cat());
}
}
结果
狗类吃饭
123AAA
小猫吃饭
123AAA
多态实现。。
多态还有两种转型 父》子 和 子》父
即上述的父类引用 = 子类示例对象 为向下转型
Animal animal = new Dog();
向下转型(强转)
Dog dog = (Dog) animal;
在学习余胜军视频后记录,当成笔记。。。