学习多态前,应当对继承和接口有一定的认识,关于博主对这二者自己的理解,可见以下:
目录
前言
在Java的世界中,多态(Polymorphism)是一个非常重要的概念,多态是使得Java的世界变得丰富多彩的重要因素之一,今天,让我们来简单了解一下多态。
引入
我们用一段简单的代码进行引入
public class Main {
public static void main(String[] args) {
Animal animal = new Cat() ;
animal.eat();
Cat cat = (Cat) animal;
cat.walk();
}
}
class Animal {
private int age;
private String name;
public Animal() {
}
public Animal(int age, String name) {
this.age = age;
this.name = name;
}
public void eat(){
System.out.println("动物吃东西");
}
}
class Cat extends Animal {
@Override
public void eat(){
System.out.println("小猫吃鱼");
}
public void walk(){
System.out.println("走猫步");
}
}
这段代码输出结果如下:
在这段代码中,子类Cat继承自父类Animal并重写了父类的方法eat(),同时有一个独有的方法walk(),在main方法中,我们通过“父类型的引用指向子类型的对象”这一理念new出了一个Animal类型的Cat对象animal,并成功通过animal调用了子类Cat的eat方法。
但当我们尝试用animal去直接调用walk方法时,却发现不能成功,而是要像上述代码一样做一个强制类型转换,将Animal类型的animal转为Cat类型的cat,再用cat去调用才可行,这是为什么呢?这就与多态的发生有一定的联系。
多态(Polymorphism)
多态的实现
在Java中,多态通过方法的重写和接口的实现来体现
- 子类可以重写父类的方法,当通过父类引用调用被子类重写的方法时,实际执行的是子类中的方法。这样就实现了多态,同一个方法可以根据不同的对象调用而表现出不同的行为。
- 通过接口实现多态性。一个接口可以被多个类实现,当调用接口中的方法时,实际执行的是对象的具体实现类中的方法。
静态绑定(编译时)
在编译时,当编译器发现程序中有方法的调用,且该方法所在的类存在于一个父子关系(接口与实现类的关系)中时,会执行静态绑定。
- 优先在父类中寻找,如果父类中有该方法,则直接绑定父类的方法(因为父类有子类必有),如上述的eat方法。
- 当父类中没有该方法时,则去子类中寻找该方法并绑定,如上述的walk方法。如果父子类中均没有该方法,则无法通过编译。
动态绑定(运行时)
运行时,则进行动态绑定,在运行时确定调用的方法。当通过父类引用调用方法时,实际执行的是对象的实际类型中的方法,而不是引用类型中的方法。
什么意思呢?我们说“父类型的引用指向子类型的对象”,那么我们通过父类型的引用(如上述animal)调用方法时,调用的是子类型的方法。而当父类型中没有该方法时,我们无法通过父类型的引用调用子类型的方法,而是需要进行类型转换(如walk方法的调用)。
总结
最后,何为多态呢?我想,编译时一种状态(静态绑定),运行时一种状态(动态绑定),这便是所谓多态 。继承关系,接口实现,都是多态的体现,可以说,由多态构建出了丰富的Java世界。
新手上路,水平有限,如有错误,还望海涵并指出!
与君共勉!