多态

本文详细介绍了Java中的面向对象特性,包括封装、继承和多态的概念。通过实例展示了多态的实现方式,如父类引用指向子类对象,以及在方法调用时的规则。此外,还探讨了多态带来的好处,如代码的灵活性。同时,提到了对象的向上转型及其安全性,并解释了如何通过向下转型来调用子类特有的方法。最后,强调了向上转型时需要注意的事项。

面向对象的三大特征:封装、继承、多态

extends继承或者implements实现,是多态性的前提。(类与类之间的继承、类与接口之间的实现、接口与接口之间的继承)。

举例,小明是一个对象,这个对象既有学生形态(子类),也有人类形态(父类)。一个对象拥有多种形态,这就是:对象的多态性

代码中体现多态性,其实就是一句话,父类引用指向子类对象。

格式:父类名称 对象名 = new 子类名称();

或者:接口名称 对象名 = new 实现类名称();

1.父子类有重名方法时。

public class Fu1 {
    public void method(){
        System.out.println("这是一个父类方法");
    }
}
public class Zi1 extends Fu1{
    @Override
    public void method(){
        System.out.println("这是一个子类方法");
    }
}
// 使用多态的写法
// 左侧父类的引用,指向了右侧子类的对象
Fu1 obj = new Zi1();
obj.method();

运行截图:

这里可以回忆前面的知识点,当根据子类对象调用成员方法时,看的是new的是谁,即看等号右边是谁,优先用谁

只有方法可以覆盖重写,变量没有。

一.访问成员变量的两种方式:

1.直接通过对象名称访问成员变量:看等号左边是谁,优先用谁,没有则向上找。(不存在向下查找)

2.间接通过成员方法访问成员变量:看该方法属于谁(覆盖重写了就属于子类了),优先用谁,没有则向上找。

public class Fu1 {
    int num = 10;
    public void show(){
        System.out.println(num);
    }
}
public class Zi1 extends Fu1{
    int num = 20;
    @Override
    public void show(){
        System.out.println(num);
    }
}
public static void main(String[] args) {
    // 使用多态的写法
    // 左侧父类的引用,指向了右侧子类的对象
    Fu1 obj = new Zi1();
    // 直接访问,左边是父类,10
    System.out.println(obj.num); // 10

    // 间接访问,方法属于父类,10
    obj.show();

    // 间接访问,重名,子类覆盖重写,属于子类,20
    obj.show();
    // System.out.println(obj.age); // 错误写法,无法向下查找
}

在多态代码中,成员方法的访问规则如上上是:看的是new的是谁,即看等号右边是谁,优先用谁

 

使用多态的好处:

无论右边new的时候换成哪个子类对象,等号左边调用方法都不会变化。

 

对象的向上转型,其实就是多态写法。

格式:父类名称 对象名 = new 子类名称();

含义:右侧创建一个子类对象,把它当作父类来看待使用。如创建了一只猫,当作动物看待,没问题。

注意事项:向上转型一定是安全的

类似于自动类型转换double num = 100; 是小范围向大范围转,是安全的。

public abstract class Animal {
    // 抽象方法
    public abstract void eat();
}
public class Cat extends Animal{

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
}
public class Demo06Main {
    public static void main(String[] args) {
        // 对象的向上转型,就是父类引用指向子类对象
        Animal animal = new Cat();
        animal.eat();
    }
}

运行截图:

向上转型是安全的,但也有弊端,如果子类有特有方法,由于向上转型为父类后不能向下查找,无法调用子类特有方法。

解决方案:用对象的向下转型【还原】(本来是子类,才能还原为子类)

格式: 子类名称 对象名 = (子类名称)父类对象;

(类似于强制类型转换)

含义:将父类对象,还原成为本来的子类对象。

 

Animal animal = new Cat(); // 本来是猫,向上转型为动物
// 本来是猫,已经被当作动物了,还原回来成为本来的猫
Cat cat = (Cat)animal;

注意事项:

1.必须保证对象本来创建的时候,就是猫,才能向下转型成为猫。

2.如果对象创建的时候不是猫,现在非要向下转型成为猫,就会报错。(编译不会报错,但是运行会出现异常ClassException)

类似于:int num = (int)10.0;//可以  int num = (int)10.5;//不可以,精度损失

 

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值