1. 多态介绍
2. 方法的多态
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public class Poly01_Method { public static void main(String[] args) { Base01 base = new Base01(); Sub01 sub = new Sub01(); base.say(); sub.say(); sub.sum(10,20); sub.sum(10,20,30); } }
class Base01 { public void say(){ System.out.println("hello Base01"); }
public void sum(int i,int j){ System.out.println(i+" + "+j+" = "+(i+j)); } }
class Sub01 extends Base01 { public void say() { System.out.println("hello Sub01"); }
public void sum(int i, int j, int k) { System.out.println(i + " + " + j + " + " + k + " = " + (i + j + k)); } }
|
3. 对象的多态
1 2 3
| 编译类型 对象名 = new 运行类型();
|
- 编译类型在定义对象时就确定了,不能改变
- 运行类型是可以变化的
- 一个对象的编译类型和运行类型可以不一致
- 对象调用方法的时候,调用的是运行类型的方法
1 2 3 4 5 6 7
| Animal animal = new Dog();
animal = new Cat();
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31
| public class PolyObject { public static void main(String[] args) { Animal animal = new Dog(); animal.say();
animal = new Cat(); animal.say(); } }
class Animal { public void say() { System.out.println("动物会叫"); } }
class Cat extends Animal { public void say() { System.out.println("小猫喵喵叫"); } }
class Dog extends Animal { public void say() { System.out.println("小狗汪汪叫"); } }
|
4. 多态代码示例
使用多态的方式能编写一个程序, 有主人类Master, 有feed 方法, 可以给不同动物喂不同食物

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75
| public class Master { public static void main(String[] args) { Animal dog = new Dog("小狗"); System.out.println(dog.name); Food dogFood = new DogFood("狗粮"); Master master = new Master(); master.feed(dog,dogFood);
Animal cat = new Cat("小猫"); Food catFood = new CatFood("猫粮"); master.feed(cat,catFood);
Animal pig = new Pig("小猪"); Food pigFood = new PigFood("猪粮"); master.feed(pig,pigFood); }
public void feed(Animal animal,Food food){ System.out.println(" 给 "+animal.name+" 喂 "+food.name); } } class Animal{ String name; public Animal(String name) { this.name = name; } } class Dog extends Animal{ String name; public Dog(String name) { super(name); this.name = name; } } class Cat extends Animal{ String name; public Cat(String name) { super(name); this.name = name; } } class Pig extends Animal{ String name; public Pig(String name) { super(name); this.name = name; } } class Food{ String name; public Food(String name) { this.name = name; } } class DogFood extends Food{ String name; public DogFood(String name) { super(name); this.name = name; } } class CatFood extends Food{ String name; public CatFood(String name) { super(name); this.name = name; } } class PigFood extends Food{ String name; public PigFood(String name) { super(name); this.name = name; } }
|
5. 多态的向上转型
语法:
1 2 3
| 编译类型 对象名 = new 运行类型(); || || || 父类类型 引用名 = new 子类类型();
|
编译类型(父类): 决定了可以调用哪些方法和属性,即:(在遵守访问权限的前提下),可以调用父类中的所有的属性和方法,也就是说无法调用子类中特有的属性和方法。
运行类型(子类):决定了属性和方法调用后的具体执行效果。如果子类没有则执行效果看父类方法。
方法的查找顺序跟继承中的方法查找顺序一致,先从子类(运行类型)中查找, 子类没有则去父类查找
属性没有重写之说,属性的值要看编译类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| public class Poly03_Upward { public static void main(String[] args) { Father06 father = new Son06();
System.out.println(father.v1); System.out.println(father.v3);
father.m1(); father.m2(); father.m3();
} } class GrandFather06{ public String v1 = "GrandFather - 10"; public String v2 = "GrandFather - 20"; private String v3 = "GrandFather - 30"; private String v4 = "GrandFather - 40";
public void m1(){ System.out.println("GrandFather method m1"); } public void m2(){ System.out.println("GrandFather method m2"); } private void m3(){ System.out.println("GrandFather method m3"); } private void m4(){ System.out.println("GrandFather method m4"); } }
class Father06 extends GrandFather06{ public String v1 = "Father - 10"; private String v2 = "Father - 20"; public String v3 = "Father - 30"; private String v4 = "Father - 40";
public void m1(){ System.out.println("Father method m1"); }
public void m3(){ System.out.println("Father method m3"); } private void m4(){ System.out.println("Father method m4"); } }
class Son06 extends Father06{ public String v1 = "Son - 10"; private String v2 = "Son - 20"; private String v3 = "Son - 30"; public String v4 = "Son - 40";
public void m1(){ System.out.println("Son method m1"); }
public void m4(){ System.out.println("Son method m4"); } }
|
6. 多态的向下转型
语法:
1 2 3
| 编译类型 对象名 = (变异类型)运行类型 || || || || 子类类型 引用名 = (子类类型)父类引用
|
只能强转父类的引用, 不能强转父类的对象
要求父类的引用必须指向的是当前目标类型的对象
当向下转型后, 可以调用子类类型中所有的成员。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53
| public class Poly04_Downward { public static void main(String[] args) { Father04 father = new Son04();
Son04 son = (Son04)father;
System.out.println(son.v1);
son.m1(); son.m2(); son.m3(); son.m4(); } } class Son04 extends Father04{ public String v1 = "Son - 10"; private String v2 = "Son - 20"; private String v3 = "Son - 30"; public String v4 = "Son - 40";
public void m1(){ System.out.println("Son method m1"); }
public void m4(){ System.out.println("Son method m4"); } } class Father04 extends GrandFather04{ public String v1 = "Father - 10"; private String v2 = "Father - 20"; public String v3 = "Father - 30"; private String v4 = "Father - 40";
public void m1(){ System.out.println("Father method m1"); }
public void m3(){ System.out.println("Father method m3"); } private void m4(){ System.out.println("Father method m4"); } } class GrandFather04{ public String v1 = "GrandFather - 10"; public String v2 = "GrandFather - 20"; private String v3 = "GrandFather - 30"; private String v4 = "GrandFather - 40";
public void m1(){ System.out.println("GrandFather method m1"); } public void m2(){ System.out.println("GrandFather method m2"); } private void m3(){ System.out.println("GrandFather method m3"); } private void m4(){ System.out.println("GrandFather method m4"); } }
|
7. 多态中的 instanceOf
instanceOf 比较操作符,用于判断对象的 执行类型是否为某类型或某类的子类型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public class Poly05_Instanceof { public static void main(String[] args) { Sub sub = new Sub(); System.out.println("sub instanceof Sub = "+(sub instanceof Sub)); System.out.println("sub instanceof Base = "+(sub instanceof Base));
Base base = new Base(); System.out.println("base instanceof Sub = "+(base instanceof Sub)); System.out.println("base instanceof Base = "+(base instanceof Base));
Sub sub2 = new Base(); System.out.println(sub.count); System.out.println("sub2 instanceof Sub = "+(sub2 instanceof Sub)); System.out.println("sub2 instanceof Base = "+(sub2 instanceof Base));
Base base2 = (Base)sub2; System.out.println("base2 instanceof Sub = "+(base2 instanceof Sub)); System.out.println("base2 instanceof Base = "+(base2 instanceof Base)); } }
class Sub{ int count = 20; }
class Base extends Sub{ int count = 10; }
|
8. 动态绑定机制
- 对象的属性没有动态绑定机制,哪里使用就调用哪里的属性
- 当调用方法的时候, 方法和运行类型(内存地址)绑定
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public class Poly06_DynamicBanding { public static void main(String[] args) { Base06 a = new Sub06(); System.out.println(a.sum1()); System.out.println(a.sum2()); System.out.println(a.i); } }
class Base06 { int i = 10;
public int sum1(){ return getI()+10; } public int sum2(){ return i+10; } public int getI() { return i; } }
class Sub06 extends Base06 { int i = 20;
@Override public int sum1(){ return i+20; } @Override public int sum2(){ return i+10; } @Override public int getI() { return i; } }
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
| public class Poly07_DynamicBanding { public static void main(String[] args) { Base07 a = new Sub07(); System.out.println(a.sum1()); System.out.println(a.sum2()); System.out.println(a.i); } }
class Base07 { int i = 10;
public int sum1(){ return getI()+10; } public int sum2(){ return i+10; } public int getI() { return i; } }
class Sub07 extends Base07 { int i = 20;
@Override public int getI() { return i; } }
|

9. 多态的应用
9.1 多态数组
数组中实际存储元素的类型为数字定义类型的子类 该数组即为多态数组
应用实例:
现在有一个继承结构如下,要求创建一个 Person 对象, 两个 Student 对象和两个Teacher 对象,放在一个数组中, 并调用每个对象的say 方法
如果调用子类特有方法, 比如Teacher 有 teach 方法, Student 类有一个study 方法, 怎么调用?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71
| public class Poly08_Array { public static void main(String[] args) { Person[] persons = new Person[4]; persons[0] = new Student("小明", 12, 90); persons[1] = new Teacher("张老师", 32, 5000); persons[2] = new Student("小红", 12, 90); persons[3] = new Teacher("李老师", 30, 6000);
for (int i = 0; i < persons.length; i++) { persons[i].say(); if (persons[i] instanceof Student) { ((Student) persons[i]).study(); } if (persons[i] instanceof Teacher) { ((Teacher) persons[i]).teach(); } } } }
class Person { public String name; public int age;
public Person(String name, int age) { this.name = name; this.age = age; } public void say() { System.out.println("讲话: "); } }
class Student extends Person { int i = 20; private int score; public Student(String name, int age, int score) { super(name, age); this.score = score; }
public void say() { super.say(); System.out.println(name+" 不懂提问"+ i); }
public void study() { System.out.println(name+" 好好学习,天天向上。"+ i); } }
class Teacher extends Person { int i = 30; private int salary; public Teacher(String name, int age, int salary) { super(name, age); this.salary = salary; }
public void say() { super.say(); System.out.println(name+" 讲课 "+ i); }
public void teach() { System.out.println(name+" 教书育人"+ i); } }
|
9.2 多态参数
传送的实参类型为形参类型的子类, 即为参数的多态
使用示例:
定义员工类(Employee), 包含姓名 和 月工资(private), 以及计算年工资的方法(getAnnual)
普通员工类 和 经理类 继承了 员工类
测试类中添加 show(Employee e) 方法 实现获取任何员工的年工资,并在main 方法中调用该方法
测试类中添加 testWork 方法,如果是普通员工,则调用work 方法, 如果是经理则调用 manage方法

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
| public class Poly09_Parameters { public static void main(String[] args) { Employee tom = new Worker("tom",1000); Employee jerry = new Manager("jerry",2000,10000);
Poly09_Parameters ploy = new Poly09_Parameters(); ploy.show(tom); ploy.show(jerry);
ploy.work(tom); ploy.work(jerry); }
public void show(Employee employee){ System.out.println(employee.getAnnual()); } public void work(Employee employee){ if(employee instanceof Worker){ ((Worker) employee).work(); } if(employee instanceof Manager){ ((Manager) employee).manage(); } } }
class Employee { public Employee(String name, double salary) { this.name = name; this.salary = salary; }
private String name; private double salary;
public double getAnnual() { return salary * 12; } } class Worker extends Employee{
public Worker(String name, double salary) { super(name, salary); }
public void work(){ System.out.println("普通员工工作"); } @Override public double getAnnual(){ System.out.println("计算员工年薪"); return super.getAnnual(); } }
class Manager extends Employee{
private double bonus;
public Manager(String name, double salary,double bonus) { super(name, salary); this.bonus = bonus; }
public void manage(){ System.out.println("管理公司"); } @Override public double getAnnual(){ System.out.println("计算经理年薪"); return super.getAnnual() + bonus; } }
|