03_面向对象高级_多态

多态

1. 什么是多态?

“多态” 是在 “继承” 的基础上实现的一种现象,具体表现为:对象多态、行为多态。

public class HelloWorld {
    public static void main(String[] args) {
        // 1. 对象多态
        Human h1 = new Student();
        Human h2 = new Teacher();

        // 2. 行为多态
        h1.run();  // 学生跑得贼快~~
        h2.run();  // 老师跑得贼快~~
    }
}

class Human {
    public void run() {
        System.out.println("人会跑步~~");
    }
}

class Student extends Human {
    public void run() {
        System.out.println("学生跑得贼快~~");
    }
}

class Teacher extends Human {
    public void run() {
        System.out.println("老师跑得贼快~~");
    }
}
2. 注意事项

多态是对象或行为的多态,Java中的属性 (成员变量) 不谈多态。

public class HelloWorld {
    public static void main(String[] args) {
        // 1. 对象多态
        Human h1 = new Student();
        Human h2 = new Teacher();

        // 2. 属性(成员变量)是没有多态的
        System.out.println(h1.name);  // "父类 Human"
        System.out.println(h2.name);  // "父类 Human"
    }
}

class Human {
    public String name = "父类 Human";
}

class Student extends Human {
    public String name = "子类 Student";
}

class Teacher extends Human {
    public String name = "子类 Teacher";
}
3. 多态的好处

3.1 在多态形式下,可以实现解耦合,右边对象可以随时切换,后续业务随机改变

// 当 Student() 不好用时,完全可以不改变下面的h1.run()...等代码,直接换成 Teacher() 即可
        Human h1 = new Student();
        h1.run();
        h1.get();
        h1.xxx......
        ......

3.2 定义方法时,使用父类类型的形参,可以接收一切子类对象,扩展性更强,更便利

public class HelloWorld {
    // main方法,程序入口
    public static void main(String[] args) {
        Human h1 = new Student();
        Human h2 = new Teacher();

        // 可以使用父类类型的变量作为形参,可以接收一切子类对象,方便到时候修改
        goToSchool(h1);
        goToSchool(h2);
    }

    // 自定义方法
    public static void goToSchool(Human h) {
        System.out.println(h + "去学校了");
    }
}

class Human {

}

class Student extends Human {

}

class Teacher extends Human {

}
4. 多态的类型转换

种类

  • 自动类型转换 —— 例如 Human h = new Teacher()
  • 强制类型转换 —— 例如 Teacher t = (Teacher) h

作用:通过把对象转换成真正的类型,从而解决了多态下不能调用子类独有方法的问题。

注意

  • 存在继承时,就可以强制类型转换,编译阶段不会报错;
  • 但是在运行阶段,如果发现对象的真实类型与强制转换后的类型不同,就会报错!( ClassCastException )
  • 因此,强制类型转换前,使用 instanceof 判断当前对象的真实类型。
public class HelloWorld {
    public static void main(String[] args) {
        // 1. 对象多态
        Human h1 = new Student();
        Human h2 = new Teacher();

        // 2. 行为多态
        h1.run();  // 学生跑得贼快~~
        h2.run();  // 老师跑得贼快~~

        // 3. 对象无法使用自己的独有功能
//      h1.test()    // 报错
//      h2.teach()   // 报错

        // 4. 想要使用独有的功能,就必须强制类型转换
        Student s = (Student) h1;
        Teacher t = (Teacher) h2;

        s.test();  // 学生需要考试
        t.teach();  // 老师需要教学

        // 5. 如果你不确定 h1 是什么类型的,强制类型转换在编译时没问题,但是运行时可能会报错
//      Teacher tt = (Teacher) h1;  // 运行报错,因为 h1 本质是Student类的对象,不可能转为Teacher类的对象

        // 6. 解决上面的问题
        judge(h1);  // 学生需要考试
    }

    // 自定义方法
    public static void judge(Human h) {
        // 6. 为了解决上面的问题方案,需要利用instanceof做个判断(类型一致返回true,否则返回false)
        if (h instanceof Teacher) {
            Teacher t = (Teacher) h;
            t.teach();
        } else if (h instanceof Student) {
            Student s = (Student) h;
            s.test();
        }
    }
}

class Human {
    public void run() {
        System.out.println("人会跑步~~");
    }
}

class Student extends Human {
    public void run() {
        System.out.println("学生跑得贼快~~");
    }

    // 学生独有功能
    public void test() {
        System.out.println("学生需要考试");
    }
}

class Teacher extends Human {
    public void run() {
        System.out.println("老师跑得贼快~~");
    }

    // 老师独有功能
    public void teach() {
        System.out.println("老师需要教学");
    }
}

你可能感兴趣的:(Java进阶,java)