java面向对象三大特征即为:继承封装多态。而多态需要三大必要条件。分别是:继承、方法重写、父类引用指向子类对象。我们先一个一个来理解。

1、首先是继承和重写。这个很简单。因为多态就是建立在不同的重写之上的。也就是说多态就是在使用着一个方法的不同重写。而重写又是依赖着继承关系。

2、这个父类引用指向子类对象。

首先先上代码示例。

public class Animal {
    public void Shout(){
        System.out.println("叫叫叫");
    }
    public void Hi(){
        System.out.println("打招呼");
    }
}
class Dog extends Animal{
    public void Shout(){
        System.out.println("汪汪汪");
    }
    public void seeHouse(){
        System.out.println("看家");
    }

}class Cat extends Animal{
    public void Shout(){
        System.out.println("喵喵喵");
    }
}

class goose extends Animal{
    public void Shout(){
        System.out.println("嘎嘎嘎");
    }
}
public class TestPolym {
    public static void main(String[] args) {
        AnimalShout(new Dog());
        AnimalShout(new goose());
    }
    static void AnimalShout(Animal animal){
        animal.Shout();
    }
}

在如上代码中,Animal类是作为dog、cat、goose的父类。而TestPolym则是用于实现多态

先解释下父类引用指向子类对象:在TestPolym类中的AnimalShout方法中,接收着Animal类的对象。这就是父类的引用;

指向子类对象则是看这一行: 

AnimalShout(new Dog());

这里其实与AnimalShout方法放在一起可以理解为:

Animal animal = new Dog();

其实这一行打出来基本就可以理解个七七八八。这句话就是定义了一个对象 animal 然后将其实例化成 类型为 Animal 的Dog()。因为Dog、Cat这些是Animal的子类,所以类型 Animal >= Dog、Cat......这些子类。所以首先指向子类是成立的。

其次在 Animal animal = new Dog(); 这个构造器真实的类型为Dog,但是! 编译器在看animal这个对象的时候,只会将他识别为Animal类型。而这行代码成立的最重要的原因是:Dog是Animal的一个子类,并且Dog类总是小于等于Animal类。然后我们看一下我们在使用什么方法。这个方法是Shout。是由Animal重写而来。因此在调用由Dog类重写Animal类的方法如此代码中的Shout方法时,此语句成立。 

反之,使用此语句去运行不是由Animal类中的方法重写而来的方法时,此语句会报错。例如用这一行去调用seeHouse时

Java 多个实现类 怎么处理走哪个_多态

 编译器会红,并且建议你在Animal中创建这样一个方法,那我们去创建一下。之后就会发现,Animal和Dog两个类中都有Hi方法了,又变成重写了!而且程序也能跑的通了。所以本质上还是Animal类包含(抽象一点的)Dog类。

 

那么我就是想在不在父类中创建这方法,并且还想通过animal类去运行seeHouse呢?这时就有了向上转型和向下转型这个概念。其中向上转型其实就是Animal animal = new Dog()这一过程。而向下转型则是将 animal 这个对象,强制转换成 Dog类型的过程。

Java 多个实现类 怎么处理走哪个_多态_02

 通过如图的方法就可以实现我们的要求。

但是这其实只是表面的美好(指编译成功),事实上有些时候会出现报错

Java 多个实现类 怎么处理走哪个_System_03

Java 多个实现类 怎么处理走哪个_父类_04

 例如我在Cat方法里新建一个CatEat方法。我想用同样的方法进行强制类型转换。编译并没有问题,但是却会报错

Java 多个实现类 怎么处理走哪个_多态_05

 报错表明Dog无法强制转换为Cat。这时候回想到上面所说的: animal 对象实际上是Dog类型,而编译器只是将他看做Animal类型。Dog 和 Cat并无继承关系,所以不可以~

之后我们加个判断语句判断一下这Cat类是否跟animal的类型一样即可~(使用instanceof语句)

 

Java 多个实现类 怎么处理走哪个_System_06