1、对象的多态性

核心内容为:Java对象的向上转型机制
(1)例1:

  1. class Person{
  2. public void print(){
  3. System.out.println("1.Person类的print方法");
  4. }
  5. }
  6. class Student extends Person{
  7. public void print(){
  8. System.out.println("2.Student类的print方法");
  9. }
  10. }
  11. public class Text1{
  12. public static void main(String[] args){
  13. Person per = new Student();//向上转型
  14. per.print();
  15. }
  16. }
  17. //运行结果:
  18. //2.Student类的print方法

Java中使用了向上转型机制,实现对象的多态性,通过父类对象的引用指向子类对象,即可直接调用子类对象重写的方法。
(2)例2:

  1. //参数统一化
  2. class Person{
  3. public void print() {
  4. System.out.println("1.Person类的print方法");
  5. }
  6. }
  7. class Student extends Person{
  8. public void print(){
  9. System.out.println("2.Student类的print方法");
  10. }
  11. }
  12. class Worker extends Person{
  13. public void print(){
  14. System.out.println("3.Worker类的Print方法");
  15. }
  16. }
  17. public class Text2{
  18. public static void main(String[] args){
  19. fun(new Person());//Person per = new Person();
  20. fun(new Student());//Person per = new Student();//向上转型 Student类 转为 Person类
  21. fun(new Worker());//Person per = new Worker();//向上转型 Worker 类 转为 Person类
  22. }
  23. public static void fun(Person per){
  24. per.print();
  25. }
  26. }
  27. //运行结果:
  28. //1.Person类的print方法
  29. //2.Student类的print方法
  30. //3.Worker类的Print方法

向上转型的核心在于使用哪个类型的构造器new的空间并且调用方法是否被重写。
向下转型机制有安全隐患不建议使用。

2、方法的多态性

多态分成两类
(1)前期绑定(方法重载)
又称为编译时多态。

  1. class Person{
  2. public void say(){
  3. }
  4. public void say(String s){
  5. }
  6. public void say(String s1, String s2){
  7. }
  8. }

类似于C++的静态多态。
(2)后期绑定(方法重写)
又称为动态绑定/运行时绑定。
触发的三个必要条件:

  • 继承
  • 方法重写
  • 父类引用指向子类对象
    1. class Person{
    2. public void print(){
    3. System.out.println("1.Person类的print方法");
    4. }
    5. }
    6. class Student extends Person{
    7. public void print(){
    8. System.out.println("2.Student类的print方法");
    9. }
    10. }
    11. public class Text1{
    12. public static void main(String[] args){
    13. Person per = new Student();//向上转型
    14. per.print();
    15. }
    16. }
    17. //运行结果:
    18. //2.Student类的print方法
    子类Student重写了父类Person的方法print(),父类对象的引用per指向子类对象Student(),调用per的print()方法时实际上使用的是Student的print()。运行时才知道per要绑定的是Student对象。

缺陷:
(1)私有方法覆盖问题
私有方法无法覆盖因此不能实现重写,此时实现多态会失败,依然执行的是父类的私有方法。要小心父类的私有方法不能跟子类的方法重名。
(2)域和静态方法
方法调用时只能使用普通的调用,super之类的其他调用会使得多态失败。

3、构造器和清理的多态性

(1)构造器复用类中已提及,构造器连接从子类开始向上链接,运行时从根父类开始向下允许每一层构造器。

(2)清理
子类的清理方法必须调用父类的清理方法,然后再单独清理子类的内容,否则会出现父类内容未清理的情况。

4、协变返回类型

多态实现的同时,方法的返回值类型type可以被改变,此时,父类对象引用调用方法时,返回值的类型可以是type也可以是type的子类。

  1. package Animal;
  2. public class CovariantDemo {
  3. public static void main(String[] args) {
  4. Animal animal=new Animal();
  5. Food food=animal.behavior();
  6. food.eat();
  7. Dog dog=new Dog();
  8. Bone bone=dog.behavior();
  9. bone.eat();
  10. }
  11. }
  12. //基类
  13. class Animal{
  14. public Food behavior(){
  15. System.out.println("Animal:");
  16. return new Food();
  17. }
  18. }
  19. //子类
  20. class Dog extends Animal{
  21. @Override
  22. public Bone behavior(){
  23. System.out.println("Dog:");
  24. return new Bone();
  25. }
  26. }
  27. class Food{
  28. public void eat(){
  29. System.out.println("Animal like to eat food");
  30. }
  31. }
  32. class Bone extends Food{
  33. @Override
  34. public void eat(){
  35. System.out.println("Dogs like to eat bones");
  36. }
  37. }

这基于里氏替换原则:任何父类可以出现的地方,子类也可以出现。