12Java基础之多态

多态

  • 多态是在继承/实现情况下的一种现象,表现为:对象多态、行为多态。

  • 多态存在的条件

    • 有继承关系
    • 子类重写父类的方法
    • 父类引用指向子类对象

多态的一个注意事项

  • 多态是对象、行为的多态,Java中的属性(成员变量)不谈多态。
    案例:
父类:
public class Animal {
    public String name ="动物名称";
   
    public void cry(){
        System.out.println("动物会叫");
    }
}

子类:
public class Cat extends Animal{
    public String name = "猫的名称";
    
    @Override
    public void cry(){
        System.out.println("喵喵叫");
    }
}

public class Dog extends Animal{
    public String name = "狗的名称";
    @Override
    public void cry(){
        System.out.println("汪汪叫");
    }
}

main方法:
   public static void main(String[] args) {
    // 对象多态
    Animal c = new Cat();
    Animal d = new Dog();
    c.cry();// 编译看左边,运行看右边
    d.cry();
    System.out.println(c.name);// 成员变量:编译看左,运行也看左。
    System.out.println(d.name);
} 
输出结果:
喵喵叫
汪汪叫
动物名称
动物名称

使用多态的好处

  • 在多态形式下,右边对象时解耦合的,更便于拓展和维护。
  • 定义方法时,使用父类类型的形参,可以接收一切子类对象,拓展性更强、更便利。
    案例:
父类:
public class Animal {
    public void cry(){
        System.out.println("动物会叫");
    }
}

子类:
public class Cat extends Animal{
    @Override
    public void cry(){
        System.out.println("喵喵叫");
    }
}

public class Dog extends Animal{
    @Override
    public void cry(){
        System.out.println("汪汪叫");
    }
}

main方法:
public static void main(String[] args) {
        // 1. 多态下右边对象时解耦合的。
//        Animal a = new Cat();
    Animal a = new Dog();
    a.cry();

    Cat c = new Cat();
    go(c);

    Dog d = new Dog();
    go(d);
    System.out.println("--------------------------------");

}

// 2.多态下,父类类型作为方法的形参,可以接收一切子类对象,方法更便利。
public static void go(Animal c){
    System.out.println("开始。。。");
    c.cry();// 对象回调
    // 多态下存在的一个问题:不能调用子类独有的功能方法
//        c.lookDoor();   // 报错
//        c.catchMouse(); // 报错
    System.out.println("结束。。。");
}
输出结果:
汪汪叫
开始。。。
喵喵叫
结束。。。
开始。。。
汪汪叫
结束。。。
  • 多态下存在一个问题:不能调用子类独有的功能方法。

多态下类型转换问题

  • 类型转换

    1. 自动类型转换:父类 变量名 = new 子类()。例如:People p = new Teacher();
    2. 强制类型转换:子类 变量名 = (子类)父类变量。例如:Teacher t = (Teacher)p;
  • 强制类型转换的一个注意事项

    1. 存在继承/实现关系就可以在编译阶段进行强制类型转换,编译阶段不会报错。
    2. 运行时,如果发现对象的真实类型与强转后的类型不同,就会报类型转换异常(ClassCastException)的错误出来
  • 强制类型转换前,Java建议我们去做什么事情?

  • 建议使用instanceof判断当前对象的真实类型:对象 instanceof 类型

案例:

父子类沿用上边的动物类和猫类、狗类
main方法:
public static void main(String[] args) {
        // 1. 多态下右边对象时解耦合的。
    Animal a = new Dog();
    a.cry();

    // 强制类型转换:可以解决多态下不能直接调用子类的方法的问题。
    Dog d = (Dog)a;
    d.lookDoor();

    // 强制类型转换的注意事项:1.只要有继承或者实现关系的两个类就可以强制转换。
    // 编译阶段不会报错(写代码),但是运行时可能出现强制类型转换异常。
//        Cat c = (Cat) a;// 编译不报,运行时会报错
    Cat c = new Cat();
    go(c);

}

// 2.多态下,父类类型作为方法的形参,可以接收一切子类对象,方法更便利。
public static void go(Animal a){
    System.out.println("开始。。。");
    a.cry();// 对象回调
    //因此,Java建议强制类型转换之前,先判断对象的真实类型,在进行强转。
    if(a instanceof Dog){
        Dog d1 = (Dog)a;
        d1.lookDoor();
    }
    else if(a instanceof Cat){
        Cat c1 = (Cat)a;
        c1.catchMouse();
    }
    else{
        System.out.println("不是狗,不能强转");
    }
    System.out.println("结束。。。");
}

输出结果:
汪汪叫
狗会看门
开始。。。
喵喵叫
猫会抓老鼠
结束。。。
posted @ 2025-07-24 09:09  狂风将军  阅读(10)  评论(0)    收藏  举报