Java编程

java多态教程

多态性是一种对象采取多种形式的能力。 当父类引用用于引用子类对象时,通过就会使用OOP中的多态性。

任何通过多个IS-A测试的Java对象都被认为是多态的。 在Java中,所有Java对象都是多态的,因为任何对象都会为自己的类型和类对象传递IS-A测试。

重要的是要知道访问对象的唯一方法是通过引用变量。 引用变量只能是一种类型。 声明后,无法更改引用变量的类型。

如果未将引用变量声明为final,则可以将引用变量重新分配给其他对象。 引用变量的类型将确定它可以在对象上调用的方法。

引用变量可以引用其声明类型的任何对象或声明类型的任何子类型。 引用变量可以声明为类或接口类型。

public interface Vegetarian{}public class Animal{}public class Deer extends Animal implements Vegetarian{}现在,可将Deer类认为是多态的,因为它具有多重继承。示例说明如下:

Deer IS-A AnimalDeer IS-A VegetarianDeer IS-A DeerDeer IS-A Object当将引用变量应用于Deer对象引用时,以下声明是合法的 –

Deer d = new Deer();Animal a = d;Vegetarian v = d;Object o = d;所有引用变量:d,a,v,o都指向堆中的同一个Deer对象。

虚拟方法在本节中,将演示如何在Java中重写方法的行为,以在设计类时利用多态性。

前面章节中已经学习了方法覆盖,子类可以覆盖父级中的方法。重写方法基本上隐藏在父类中,除非子类在重写方法中使用super关键字,否则不会调用父类方法。

// 文件: Employee.javapublic class Employee {private String name;private String address;private int number;public Employee(String name, String address, int number) {System.out.println(“构造一个:Employee”);this.name = name;this.address = address;this.number = number;}public void mailCheck() {System.out.println(“发送邮件检查:” + this.name + ” ” + this.address);}public String toString() {return name + ” ” + address + ” ” + number;}public String getName() {return name;}public String getAddress() {return address;}public void setAddress(String newAddress) {address = newAddress;}public int getNumber() {return number;}}现在扩展Employee类如下 –

// 文件 : Salary.javapublic class Salary extends Employee {private double salary; // Annual salarypublic Salary(String name, String address, int number, double salary) {super(name, address, number);setSalary(salary);}public void mailCheck() {System.out.println(“在Salary类中的 mailCheck()方法”);System.out.println(“发送邮件检查:” + getName() + ” with salary ” + salary);}public double getSalary() {return salary;}public void setSalary(double newSalary) {if (newSalary >= 0.0) {salary = newSalary;}}public double computePay() {System.out.println(“计算应付工资:” + getName());return salary / 52;}}仔细研究下面的程序并尝试判断它的输出结果 –

// 文件:VirtualDemo.javapublic class VirtualDemo {public static void main(String[] args) {Salary s = new Salary(“Maxsu”, “Renmin Road No.688 Haikou”, 3, 9600.00);Employee e = new Salary(“董小姐”, “Daxing Road No.188 Haikou”, 2, 8400.00);System.out.println(“调用 Salary 类引用的 mailCheck()方法”);s.mailCheck();System.out.println(“调用 Employee 类引用的 mailCheck()方法”);e.mailCheck();}}执行上面示例代码,得到以下结果 –

构造一个:Employee构造一个:Employee调用 Salary 类引用的 mailCheck()方法在Salary类中的 mailCheck()方法发送邮件检查:Maxsu with salary 9600.0调用 Employee 类引用的 mailCheck()方法在Salary类中的 mailCheck()方法发送邮件检查:董小姐 with salary 8400.0在上面代码中,实例化两个Salary对象。一个使用Salary类的引用s,另一个使用Employee类引用e。

在调用s.mailCheck()时,编译器在编译时看到Salary类中有mailCheck()方法,并且JVM在运行时调用Salary类中的mailCheck()方法。

e实例变量的mailCheck()是完全不同的,因为e是一个Employee引用。 当编译器看到e.mailCheck()时,编译器会在Employee类中找到mailCheck()方法。

在编译时,编译器使用Employee中的mailCheck()执行验证。但是,在运行时,JVM调用Salary类中的mailCheck()方法。

此行为称为虚方法调用,这些方法称为虚方法。 无论在编译时源代码中使用的引用是什么数据类型,都会在运行时调用重写方法。

Similar Posts

发表评论

邮箱地址不会被公开。 必填项已用*标注