前言
在面向对象(OOP)的程序设计语言中,多态与封装、继承合称为OOP的三大特性。在今天,我们就来学习一下JAVA中的多态是什么样子的。、
多态
指一个对象在不同情况下可以表现出不同的行为。Java多态性分为两种:编译时多态性(静态多态性)和运行时多态性(动态多态性)。
编译时多态性:也称为静态多态性,是指在编译期间就能确定方法的调用方式、参数类型及返回值类型等,主要通过方法重载实现。
运行时多态性:也称为动态多态性,是指在运行期间才能确定方法的调用方式,主要通过方法重写实现。Java中实现运行时多态性的关键是继承和方法重写。
具体来说,当一个类的子类重新定义了一个或多个已在父类中定义的方法时,那么子类的对象将可以调用重新定义的方法,而不是调用父类中的方法。这种现象称为方法重写。当通过父类的引用变量来引用一个子类的对象时,父类引用变量不能直接调用子类中重新定义的方法,而是要调用子类中的方法,这种多态性称为动态多态性。
多态实现的重要条件
Java多态实现的重要条件包括:
- 继承:
必须有继承关系,子类必须继承父类
。- 覆盖:子类必须
重写父类的方法
。- 向上转型:可以声明一个
父类引用类型
的变量,将它指向一个子类对象。通过这种方式调用方法,就可以实现多态。- 动态绑定:在运行时而
不是编译时进行方法调用
。这样就能够根据实际调用的对象类型来决定调用哪个方法,实现多态。
虚函数
在Java中,所有方法都是虚函数,因为它们都是在运行时动态绑定的。当子类继承父类时,它可以覆盖父类的方法,但具体调用哪个方法取决于对象的实际类型而不是变量的声明类型。因此,可以在运行时动态处理对象的多态性。
使用关键字“override”来覆盖父类的方法。子类中的方法必须与父类中被覆盖的方法具有相同的名称、参数列表和返回类型。这样,当调用子类中的方法时,根据对象的类型来确定应该调用哪个方法。
实例
假设我们有一个Animal类和一个Cat类,Cat类是Animal类的子类。
Animal类中定义了一个虚方法makeSound(),它会输出动物发出的声音:
public class Animal { public void makeSound() { System.out.println("The animal makes a sound"); } }
Cat类继承了Animal类并覆盖了makeSound()方法:
public class Cat extends Animal { public void makeSound() { System.out.println("The cat meows"); } }
现在,我们可以实例化一个Animal对象和一个Cat对象,并调用它们makeSound()方法:
Animal animal = new Animal(); Cat cat = new Cat(); animal.makeSound(); // 输出 "The animal makes a sound" cat.makeSound(); // 输出 "The cat meows"
注意,由于Cat类继承了Animal类,因此可以使用Cat对象来代替Animal对象,因为它们都是Animal类的实例。这就是面向对象编程中的多态性。
多态的实现方式
方式一:重写:
这个内容已经在上一篇文章中我有详细的讲过Java 重写(Override)与重载(Overload)
方式二:接口
- 生活中的接口最具代表性的就是插座,例如一个三接头的插头都能接在三孔插座中,因为这个是每个国家都有各自规定的接口规则,有可能到国外就不行,那是因为国外自己定义的接口类型。
- java中的接口类似于生活中的接口,就是一些方法特征的集合,但没有方法的实现。具体可以看 java接口 这一章节的内容。
方式三:抽象类和抽象方法