面向对象的三大特点解析
面向对象的三大特点解析
多态
多态存在的三个必要条件:继承、重写、父类引用指向子类对象
满足以上三个条件时,当使用多态方式调用方法的时候,首先看父类中是否已经有这个方法,没有的话编译错误;有的话再去调用子类中同名的方法!!!
首先举个栗子(例题来自于度小满研发岗笔试题以及CSDN博客):
public class Main{
public static void main(String args[]){
Animal a = new Animal(); // Animal 对象
Animal b = new Dog(); // Dog 对象
a.move();// 执行 Animal 类的方法
b.move();//执行 Dog 类的方法
b.bark();
}
}
class Animal{
public void move(){
System.out.println("动物可以移动");
}
public void run(){
System.out.println("动物可以奔跑");
}
}
class Dog extends Animal{
public void move(){
System.out.println("狗可以跑和走");
}
public void bark(){
System.out.println("狗可以吠叫");
}
}
这段代码运行后编译器会报错,Animal b=new Dog();这是Java的多态,表示由父类的引用指向子类对象,这里编译器首先在父类中寻找bark()方法,但是发现没有,那么编译器就会报错
应该改成:
public class Main{
public static void main(String args[]){
Animal a = new Animal(); // Animal 对象
Dog b = new Dog(); // Dog 对象
a.move();// 执行 Animal 类的方法
b.move();//执行 Dog 类的方法
b.bark();
}
}
class Animal{
public void move(){
System.out.println("动物可以移动");
}
}
class Dog extends Animal{
public void move(){
System.out.println("狗可以跑和走");
}
public void bark(){
System.out.println("狗可以吠叫");
}
}
那么当执行Animal b=new Dog()时,内存中发生了什么呢?
起初创建的子类对象中有子类重写的子类类型的父类方法、子类自己创建的方法以及子类中继承的父类但是没有重写的父类方法;
当上转型发生后,会丢失子类的新增方法,保留子类的重写方法,这也就是上面报错的原因。
对应的Java另一种多态——向下转型:
代码如下:
public class Main{
public static void main(String args[]){
Animal a = new Animal(); // Animal 对象
Animal b = new Dog(); // Dog 对象
Dog d=(Dog)b;//向下转型
a.move();// 执行 Animal 类的方法
b.move();//执行 Dog 类的方法
b.bark();
}
}
class Animal{
public void move(){
System.out.println("动物可以移动");
}
public void run(){
System.out.println("动物可以奔跑");
}
}
class Dog extends Animal{
public void move(){
System.out.println("狗可以跑和走");
}
public void bark(){
System.out.println("狗可以吠叫");
}
}
当执行Animal b=new Dog(); Dog d=(Dog)b;内存又发生了什么呢?
通过下转型后又重新得到了子类新增的方法,上述的错误也可以在加一个下转型来实现