[Java进阶] 面向对象特性---多态

本文探讨了多态的定义、访问特性,展示了其在父类引用下如何通过子类对象、方法参数和返回值隐藏实现。同时揭示了多态的局限性和解决方法,包括向下转型和instanceof的使用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

多态

多态的前提:

多态的概念:

多态的定义:

多态的访问特点

使用父类引用访问成员变量

使用父类引用访问成员方法

多态的应用

1.  父类引用访问子类对象

2.  隐藏在方法参数

3.  隐藏在返回值

多态的弊端与解决办法


多态

多态的前提:

1. 满足继承关系或者实现关系(两个以上的类)         2. 有方法的重写(不强制, 但是不重写没意义)

多态的概念:

指的是一个事物在不同时刻下体现的不同形态,子类当下是以子类自身还是父类的形态去体现

多态的定义:

已有Cat类继承了Animal类, 用父类引用指向子类对象(表现形式)

Animal a = new Cat();

多态的访问特点

多态的分析分为编译和运行两个阶段,编译过程中父类引用会在父类中找调用的属性或者方法,能找到则编译通过

使用父类引用访问成员变量

编左看左: 编译和运行都看左边父类, 也就是说编译运行都看父类的成员变量值

public abstract Animal{
    String name;
    int age;
}
class Cat extends Animal{
    int age = 10;
}

class Test{
    public static void main(String[] args){
        Animal a = new Cat();
        System.out.println(a.age);
    }
}

使用父类引用访问成员方法

编左看右: 编译看左边,运行看右边, 父类有该成员方法才能编译通过,但运行时访问的是子类重写后的方法

public abstract Animal{
    public abstract void eat();
}
class Cat extends Animal{
    public void eat(){
        System.out.println("猫吃鱼..");
    }
}

class Test{
    public static void main(String[] args){
        Animal a = new Cat();
        a.eat();
    }
}

多态的应用

1.  父类引用访问子类对象

public abstract Animal{
    String name;
    int age;
    public abstract void eat();
}
class Cat extends Animal{
    int age = 10;
    public void eat(){
        System.out.println("猫吃鱼..");
    }
}

class Test{
    public static void main(String[] args){
        Animal a = new Cat();
        System.out.println(a.age);
        a.eat;
    }
}

2.  隐藏在方法参数

public abstract Animal{
    public abstract void eat();
}
class Cat extends Animal{
    public void eat(){
        System.out.println("猫吃鱼..");
    }
}

class Test{
    public static void main(String[] args){
        Cat cat = new Cat();
        //多态体现在这一步
        useEat(cat);
    }
    public static void useEat(Animal a){
        a.eat();
    }
}

3.  隐藏在返回值

public interface Flyable{
//接口中方法不写public abstract 也会默认加上
    void fly();
}

class Bird implement Flyable{
    public void fly(){
        System.out.println("小鸟扇动翅膀飞...");
    }
}
class Plane implement Flyable{
    public void fly(){
        System.out.println("飞机靠发动机飞...");
    }
}
class Test{
    public static void main(String[] args){
        //toFly()的返回值是Flyable  因此只能用Flyable的引用接收
        Flyable f = toFly();
    }

    //这里的返回值是Flyable  因此只能用Flyable的引用接收
    public static Flyable toFly(){
        if(new Random().nextInt(10)%2==0){
            return new Bird();
        }else{
            return new Plane();
        }
    }
}

多态的弊端与解决办法

在使用多态的过程中, 无论是访问成员变量还是成员方法, 只能访问父类已存在的内容无法访问子类特有的属性和方法, 否则编译不通过

针对这种情况,我们可以使用向下转型, 将父类引用更改为子类引用指向子类对象.

Animal a = new Cat();
//父类引用只能使用父类存在的方法
a.eat();
//向下转型后的子类对象可以调用子类独有的方法
Cat cat = (Cat)a;//需要强转
cat.catch();

在使用编写程序时 instanceof关键字 判断子类是否是父类 让我们更灵活使用多态的向下转向型

eg : cat instanceof Animal  (true)

    public static void useUsb(USB usb){
        //USB对象特有方法
        usb.powerOn();
        //如果传进来的USB 是Mouse,向下转型成Mouse,执行Mouse特有的方法
        if (usb instanceof Mouse){
            Mouse mouse  = (Mouse) usb;
            mouse.click();
        //如果传进来的usb是Keyboard,向下转型成Keyboard,执行Keyboard特有的方法
        }else if (usb instanceof Keyboard) {
            KeyBoard keyBoard = (KeyBoard) usb;
            keyBoard.enter();
        }
        //USB对象特有方法
        usb.powerOff();
    }

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值