Java入门第34课:多态、向上转型、动态绑定

一、学习目标

  1. 理解面向对象三大特性:多态的概念与价值
  2. 掌握多态的实现条件
  3. 学会向上转型、向下转型语法与场景
  4. 分清成员变量、成员方法在多态下的访问规则
  5. 理解动态绑定机制
  6. 掌握转型异常判断 instanceof

二、什么是多态

多态:同一个行为,不同对象执行有不同表现形态。 举例: 父类 Animal 有 eat () 方法,Dog、Cat 子类重写 eat (); 同样调用 eat (),狗是啃骨头,猫是吃鱼,这就是多态。

多态核心好处:程序扩展性强,新增子类不用修改原有业务代码。

三、多态实现的四个必备条件(缺一不可)

  1. 存在继承 / 实现关系(extends /implements)
  2. 子类重写父类方法
  3. 父类引用指向子类对象(向上转型)
  4. 调用重写的方法

基础代码演示

java运行

// 父类
abstract class Animal {
    public abstract void eat();
}
// 子类狗
class Dog extends Animal {
    @Override
    public void eat() {
        System.out.println("狗啃骨头");
    }
}
// 子类猫
class Cat extends Animal {
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}

public class Test {
    public static void main(String[] args) {
        // 父类引用指向子类对象:向上转型,多态写法
        Animal a1 = new Dog();
        Animal a2 = new Cat();

        // 同一个eat方法,不同对象不同实现(多态体现)
        a1.eat();
        a2.eat();
    }
}

运行结果:

plaintext

狗啃骨头
猫吃鱼

四、向上转型(自动转换)

语法

java

运行

父类类型 引用变量 = new 子类对象();
  1. 自动转换,无需强转
  2. 访问权限限制:
    • 只能调用父类中存在的方法 / 变量
    • 子类独有的方法无法直接调用

示例缺陷

java运行

class Dog extends Animal{
    @Override
    public void eat(){}
    // 子类独有方法
    public void watchHome(){
        System.out.println("看家");
    }
}
public static void main(String[] args) {
    Animal a = new Dog();
    a.eat();        // 正常,父类有eat
    // a.watchHome(); 编译报错,父类没有该方法
}

五、向下转型(强制转换)

需求:向上转型后,想调用子类独有方法,需要向下强制转回子类类型。

语法

java运行

子类类型 变量 = (子类类型)父类引用;

java运行

Animal a = new Dog();
Dog dog = (Dog) a;
dog.watchHome(); // 可以调用子类独有方法

转型风险:类型转换异常 ClassCastException

如果父类引用实际指向的是另一个子类,强转会报错

java运行

Animal a = new Cat();
Dog dog = (Dog) a; // 运行报错:Cat不能转Dog

六、instanceof 关键字(安全转型必备)

作用:判断引用变量实际对象是不是某个类 / 子类,返回布尔值 语法:

java运行

引用变量 instanceof 类名

标准安全转型写法:

java运行

Animal a = new Dog();
if(a instanceof Dog){
    Dog dog = (Dog)a;
    dog.watchHome();
}
if(a instanceof Cat){
    Cat cat = (Cat)a;
}

七、多态访问规则(重点必背)

1. 成员方法:编译看左边,运行看右边(动态绑定)

  • 编译阶段:检查父类是否有该方法,没有则报错
  • 运行阶段:执行子类重写后的方法

2. 成员变量:编译看左边,运行看左边(静态绑定)

变量不存在重写,永远取引用类型(父类)的变量 完整对比案例:

java运行

class Father{
    String name = "父类";
    public void show(){
        System.out.println("父类方法");
    }
}
class Son extends Father{
    String name = "子类";
    @Override
    public void show(){
        System.out.println("子类方法");
    }
}
public class Test{
    public static void main(String[] args) {
        Father f = new Son();
        // 变量:看左边Father
        System.out.println(f.name); // 输出:父类
        // 方法:运行看右边Son
        f.show(); // 输出:子类方法
    }
}

八、多态经典应用:方法参数多态

定义统一方法接收父类类型,所有子类对象都能传入,扩展性极强

java运行

public class TestAnimal {
    // 参数为父类,所有子类都可以传入
    public static void feed(Animal a){
        a.eat();
    }
    public static void main(String[] args) {
        feed(new Dog());
        feed(new Cat());
    }
}

后续新增兔子 Rabbit 子类,不需要修改 feed 方法,直接传入即可,符合开闭原则。

九、向上 / 向下转型总结

表格

转型语法转换方式特点
向上转型父类 引用 = new 子类 ()自动转换只能访问父类方法,丢失子类独有功能
向下转型子类 引用 = (子类) 父类引用强制转换可调用子类独有方法,有类型转换异常风险,需配合 instanceof

十、常见易错点

  1. 多态父类引用无法直接调用子类独有方法,必须向下转型
  2. 向下转型不判断 instanceof,容易运行时报 ClassCastException
  3. 成员变量不存在重写,多态下永远取父类变量
  4. 静态方法不存在重写,多态调用静态方法只看左边引用类型

十一、课堂练习

  1. 抽象父类 Shape,抽象方法 getArea () 求面积
  2. 子类 Rect 矩形、Circle 圆形重写求面积
  3. 写静态方法 printArea (Shape s),传入任意图形输出面积(多态参数)

十二、课后作业

  1. 接口 USB,方法 work ();鼠标 Mouse、键盘 Keyboard 实现 USB
  2. 多态写法:USB usb1 = new Mouse (); USB usb2 = new Keyboard ();
  3. 使用 instanceof 判断类型,向下转型调用子类独有方法

本课小结

  1. 多态三要素:继承 / 实现、方法重写、父类引用指向子类对象;
  2. 方法动态绑定:编译看父类,运行执行子类重写方法;
  3. 向上转型自动转换,向下强制转型,配合 instanceof 避免异常;
  4. 多态最大优势:统一参数,拓展性强。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值