[学习笔记]Java多态性

来源:互联网 发布:mac装好windows没wifi 编辑:程序博客网 时间:2024/05/18 17:42

概述

定义

事物存在的多种体现形态。比如,猫和狗都是动物的一种,继承自动物,可以创建一个猫变量,指向一个具体的猫对象,也可以创建一个动物变量,指向一个具体的猫对象,这种特性就是多态。

体现

父类的引用指向了子类对象,父类的引用也可以接收子类对象。
重载和重写就是函数的多态性体现。

前提

必须是类与类之间有继承或实现关系,通常存在重写。

作用

多态的存在提高了程序的扩展性和后期的可维护性,但是只能使用父类的引用访问父类中的成员。

注意

1. 不可以将父类对象转成子类类型。子类对象的引用可以被向上转型(类型提升)和向下转型(强制转换),多态始终是子类对象做变化。
2. instanceof类型判断关键字,一般用于子类型有限的时候。

示例

/**
* 多态基本示例程序
* Employee类为超类,Manager类和Programmer类是Employee类的子类,重写了超类中的getSalary()和work()方法,
* 同时Manager类也有自己的实例域bonus和方法Meeting()。
*
* 如下所示:
* Employee (name salary | raiseSalary() getSalary() work())
* |--Manager (bonus | getSalary() meeting())
* |--Programmer (-)
*/
abstract class Employee {
String name;
double salary;
 
public Employee(String n, double s) {
name = n;
salary = s;
}
 
void raiseSalary(double byPercent) {
salary += salary * byPercent / 100;
}
 
abstract double getSalary();
 
abstract void work();
}
class Manager extends Employee {
private double bonus;
 
public Manager(String n, double s) {
super(n, s);
bonus = s * 2;
}
 
public void raiseSalary(double byPercent) {
super.raiseSalary(byPercent);
bonus += bonus * byPercent / 100;
}
 
public double getSalary() {
return salary * 12 + bonus;
}
 
public void work() {
System.out.println("Manager Work!");
}
 
public void meeting() {
System.out.println("Manager Meeting!");
}
}
class Programmer extends Employee {
public Programmer(String n, double s) {
super(n, s);
}
 
public double getSalary() {
return salary * 12 * 1.06;
}
 
public void work() {
System.out.println("Coding...");
}
}
public class PolyDemo {
public static void main(String[] args) {
Employee[] staff = new Employee[3];
staff[0] = new Manager("BOSS", 10000); // 向上转型(类型提升)
staff[1] = new Programmer("p1", 5000);
staff[2] = new Programmer("p2", 6000);
 
for (Employee e : staff) {
e.work();
e.raiseSalary(10); // 不同对象,涨薪的方式不同,调用了不同的raiseSalary()函数。
if (e instanceof Manager) {
Manager m = (Manager) e; // 向下转型(强制类型转换)
m.meeting();
}
}
for (Employee e : staff) {
System.out.println("name = " + e.name + "\tsalary = " + e.getSalary());
// 不同对象,薪资计算方法不同,调用了不同子类的getSalary()函数。
}
 
// Manager m = new Employee(); //错误,不可将父类对象转成子类类型,多态始终变化的是子类对象。
}
}

运行结果

Manager Work!
Manager Meeting!
Coding...
Coding...
name = BOSS salary = 154000.0
name = p1 salary = 69960.0
name = p2 salary = 83952.0

多态中的成员

对于多态非静态方法

编译时期:参阅引用变量所属的类中是否有调用的方法,若没有,编译失败。
运行时期:参阅对象所属的类中是否有调用的方法,若没有,则按该对象所属的类的超类方法运行。
即:方法在多态调用时,编译看左边,运行看右边。

对于多态静态方法

无论编译和运行,都参阅引用变量所属的类(左边)。

对于多态实例域

无论编译和运行,都参考引用变量所属的类(左边)。

示例

class Father {
int num1 = 1;
static int num2 = 2;
 
void func1() {
System.out.println("Father Func_1");
}
 
void func2() {
System.out.println("Father Func_2");
}
 
static void func4() {
System.out.println("Father Static Func_4");
}
}
class Son extends Father {
int num1 = 11;
static int num2 = 22;
 
@Override
void func1() {
System.out.println("Son Func_1");
}
 
void func3() {
System.out.println("Son Func_3");
}
 
// 没有覆盖超类的func4()方法
static void func4() {
System.out.println("Son Static Func_4");
}
}
class PolyDemo {
public static void main(String[] args) {
Father f = new Son();
f.func1(); // 执行的是子类的func1()
f.func2();
// f.func3(); //错误,编译时检查到Father类型中无func3函数。
 
System.out.println("--------------");
 
Son s = new Son();
s.func1();
s.func2();
s.func3();
 
System.out.println("--------------");
 
System.out.println("f.num1 = " + f.num1); // 实际使用的是变量所属类的实例域
System.out.println("s.num1 = " + s.num1);
 
System.out.println("--------------");
 
f.func4();
s.func4();
// 静态成员函数一般不需要对象,不可继承不可重写,建议直接使用类名调用,执行的是变量所属类的静态方法。
 
System.out.println("--------------");
 
System.out.println("f.num2 = " + f.num2); // 静态域同静态方法
System.out.println("s.num2 = " + s.num2);
}
}

运行结果

Son Func_1
Father Func_2
--------------
Son Func_1
Father Func_2
Son Func_3
--------------
f.num1 = 1
s.num1 = 11
--------------
Father Static Func_4
Son Static Func_4
--------------
f.num2 = 2
s.num2 = 22

实例

笔记本电脑运行实例,其中包括需要运行USB设备。由于USB设备不确定,后期也可能添加或移除。所以定义USB接口,凡是USB设备均实现这个接口,并通过这个接口调用USB设备的运行,提高程序的可扩展性和后期可维护性。
/**
* USB接口标准,所有的扩展设备均在这个接口上工作,提供了两个抽象方法,是设备运行的必备方法。
*/
interface USB {
public abstract void open();
 
public abstract void close();
}
 
/**
* 笔记本电脑类
*/
class Notebook {
// 实际USB接口和已使用的USB接口数量
USB[] device = new USB[10];
int numUsb = 0;
 
/*
* 运行方法,包括笔记本电脑的运行和所有USB设备的运行。
* 这里调用的是USB接口中的运行方法,其具体实现在子类(具体的USB设备)中定义。
* 用这种方式设计可以提高程序扩展性。
*/
public void run() {
System.out.println("Notebook Open!");
for (int i = 0; i < numUsb; i++)
openUsb(device[i]);
 
System.out.println("...Running...");
for (int i = 0; i < numUsb; i++)
closeUsb(device[i]);
 
System.out.println("Notebook Close!");
}
 
// 添加USB设备
public void addUsb(USB p) {
device[numUsb] = p;
numUsb++;
}
 
// 移除对应USB设备
public void deleteUsb(USB p) {
for (int i = 0; i < numUsb; i++) {
if (device[i] != p)
continue;
else {
for (int j = i; j < numUsb - 1; j++) {
device[j] = device[j + 1];
}
numUsb--;
break;
}
}
}
 
// 若USB接口上有设备,则运行该设备
public void openUsb(USB p) {
if (p != null) p.open();
}
 
// 若USB接口上有设备,则关闭该设备
public void closeUsb(USB p) {
if (p != null) p.close();
}
}
 
// 定义CD-Rom设备
class CdRom implements USB {
public void open() {
System.out.println("CD-Rom Open!");
}
 
public void close() {
System.out.println("CD-Rom Close!");
}
}
 
// 定义U Disk设备
class Udisk implements USB {
public void open() {
System.out.println("U Disk Open!");
}
 
public void close() {
System.out.println("U Disk Close!");
}
}
 
public class PolyCase {
public static void main(String[] args) {
Notebook nb = new Notebook();
nb.run(); // 没有多余的USB,单独笔记本电脑运行
System.out.println("------------------------");
CdRom cd = new CdRom();
nb.addUsb(cd);
nb.run(); // 添加了CD-Rom后运行笔记本电脑
System.out.println("------------------------");
nb.addUsb(new Udisk());
nb.run(); // 添加了U Disk后运行笔记本电脑
System.out.println("------------------------");
nb.deleteUsb(cd);
nb.run(); // 移除了CD-Rom后运行笔记本电脑
}
}

运行结果

Notebook Open!
...Running...
Notebook Close!
------------------------
Notebook Open!
CD-Rom Open!
...Running...
CD-Rom Close!
Notebook Close!
------------------------
Notebook Open!
CD-Rom Open!
U Disk Open!
...Running...
CD-Rom Close!
U Disk Close!
Notebook Close!
------------------------
Notebook Open!
U Disk Open!
...Running...
U Disk Close!
Notebook Close!

0 0
原创粉丝点击