Java - Polymorphism多态
本文参考这里
多态,让一个对象拥有多种形式(forms)。
面向对象编程(OOP)中,多态的常见用法是:父类型引用,指向子类型对象(The most common use of polymorphism in OOP occurs when a parent class reference is used to refer to a child class object)。
多态
一个引用变量(reference variable)可以被声明为类class或接口interface类型。
A reference variable can refer to any object of its declared type or any subtype of its declared type.
- class型多态
- interface型多态
例子1:
public interface Vegetarian
{
}
public class Animal
{
}
public class Deer extends Animal implements Vegetarian
{
}
/*
Deer 类是多态的:
A Deer IS-A Animal
A Deer IS-A Vegetarian
A Deer IS-A Deer
A Deer IS-A Object
*/
Deer d = new Deer();
Animal a = d;
Vegetarian v = d;
Object o = d;
/* 引用变量 d,a,v,o 引用的是堆heap里同一个 Deer 对象 */
例子2,class型的多态:
/* Java的多态 */
public class PolyTest {
public static void main(String[] args) {
Flower f = new Flower();
f.sing();
/* 多态:
* - 父类型的引用,引用子类型的对象。
* - 成员在父类型(即引用变量的类型)中必须存在。
*/
Flower fr = new Rose(); // 父类型引用 fr,引用子类型对象 new Rose()
fr.sing(); // 成员方法sing()在子类型Rose中不管有没有被重写,但在父类型Flower中必须存在,因为fr是Flower型变量
Rose r = new Rose();
r.sing();
}
}
class Flower {
public Flower() {
System.out.println("flower-constructor");
}
public void sing() {
System.out.println("flower");
}
}
class Rose extends Flower {
public Rose() {
System.out.println("rose-constructor");
}
@Override
public void sing() {
System.out.println("rose");
}
}
//运行结果:
flower-constructor
flower
flower-constructor
rose-constructor
rose
flower-constructor
rose-constructor
rose
例子3,interface型的多态:
/* Java的多态 */
public class PolyTest {
public static void main(String[] args) {
MyClass a = new MyClass();
a.sayhi();
a.saybye();
/* 多态:
* - 成员在接口类型(即引用变量的类型)中必须存在,
* 这和class型多态是一样的。
*/
MyInterface b = new MyClass();
b.sayhi();
// b.saybye(); // 编译时报错:The method saybye() is undefined for the type MyInterface
}
}
interface MyInterface {
public void sayhi();
}
class MyClass implements MyInterface {
@Override
public void sayhi() {
System.out.println("class say hi");
}
public void saybye() {
System.out.println("class say bye");
}
}
// 运行结果:
class say hi
class say bye
class say hi
Java多态的方式
主要是通过三种方式:
- override:重写
- overload:重载
- 父类类型 引用子类的对象
Java的virtual式方法(Virtual Methods)
- 注意:
virtual
不是Java关键字,这里是相较于C++而言的。
/* 文件1:Employee.java */
public class Employee {
private String name;
private String address;
private int number;
// 构造函数
public Employee(String name, String address, int number) {
System.out.println("Constructing an Employee");
this.name = name;
this.address = address;
this.number = number;
}
public void mailCheck() {
System.out.println("Employee:Within mailCheck of Employee class");
}
}
/* 文件2:Salary.java */
public class Salary extends Employee {
// 构造函数
public Salary(String name, String address, int number, double salary) {
super(name, address, number);
System.out.println("Constructing an Salary");
}
public void mailCheck() {
System.out.println("Salary:Within mailCheck of Salary class");
}
}
/* 文件3:HelloJava.java */
public class HelloJava {
public static void main(String[] args) {
Employee e = new Salary("John", "Boston, MA", 2, 2400.00);
Salary s = new Salary("Lucy", "Ambehta, UP", 3, 3600.00);
System.out.println("111111");
s.mailCheck(); // 引用Salary对象
System.out.println("222222");
e.mailCheck(); // 也是引用Salary对象
}
}
// 运行结果:
Constructing an Employee
Constructing an Salary
Constructing an Employee
Constructing an Salary
111111
Salary:Within mailCheck of Salary class
222222
Salary:Within mailCheck of Salary class