Java基础,多态

多态的概述

同一个对象,在不同时刻表现出来的不同形态

举例:

多态的前提和体现

1有继承/实现关系

2有方法重写

3有父类引用指向子类对象

多态中成员的访问特点

创建Animal类

public class Animal {
    public int age = 40;
    public void eat(){
        System.out.println("动物吃东西");
    }
}

创建cat类

public class Cat extends Animal{
    public int age = 20;
    public int weight = 20;

    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
    public void playGame(){
        System.out.println("躲猫猫");
    }
}

创建animaldemo类

public class AnimalDemo {
    public static void main(String[] args) {
        //父类引用指向子类对象
        Animal animal = new Cat();
        System.out.println(animal.age);
       // System.out.println(animal.weight);
        animal.eat();
        // 报错 animal.playGame();
    }
}

执行结果

"C:\Program Files\Java\jdk1.8.0_131\bin\java.exe" "-javaagent:D:\IntelliJ IDEA com.itheima_05.AnimalDemo
40
猫吃鱼

进程已结束,退出代码0

总结:成员变量: 编译看左边,执行看右边

成员方法,编译看左边,执行看右边

其实都可以看左边,方法有重写看重写

多态的好处和弊端

好处:提高了程序的扩展性

具体体现:定义方法的时候,使用父类型作为参数,将来在使用的时候,使用具体的子类型参与操作

弊端:如果父类没有该方法,子类没有重写,则不能使用子类的特有的功能

多态中的转型:

向上转型:

从子到父

父类引用指向子类对象

向下转型:

从父到子

父类引用转为子类对象

创建Animal类

public class Animal {
    public void eat(){
        System.out.println("吃东西");
    }
}

创建Cat类

public class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫吃鱼");
    }
    public void playGame() {
        System.out.println("玩游戏");
    }
}

创建AnimalDemo类

public class AnimalDemo {
    public static void main(String[] args) {
        //多态   向上转型
        Animal animal = new Cat();

//        Cat cat = new Cat();
//        cat.eat();
//        cat.playGame();

        //向下转型
        Cat cat1=(Cat) animal;  //父类对象强制转换成子类对象   就是向下转型
        cat1.eat();
        cat1.playGame();
    }
}

特别说明:

Animal animal = new Cat();

animal.eat();编译可以通过是因为animal中有eat方法,执行的时候则是看Cat中被重写过的eat方法;

编译看左边,执行看右边

这样是可以通过animal来调用cat的eat方法了,但是我们要使用cat特有的方法的时候,就要再创建一个cat对象,这样一来就创建了两个cat对象,开辟了两次空间,非常浪费

这个时候我们可以使用向下转型,在向上转型的基础之上,将animal对象强制转换成Cat对象

即Cat cat1=(Cat) animal

这样左右两边都是Cat类,自然可以调用Cat特有的方法,play games()。

一般实际工作中person都会是一个接口,而接口不能new对象,就无法调用方法,这时候就要向上转型,再调用方法,而且只能调用接口里的方法,而不能调用实现类方法。

内存图详解

1程序开始,main方法先被加载到栈内存,

然后Animal a 被加载到main方法中,

new Cat在堆内存中开辟空间,地址值为001,并把地址值给Animal a

到这里是多态的形式,向上转型

在多态中,编译看左边,执行看右边

这时候就要调用Cat中的eat方法,所以Cat类和方法eat被加载到栈内存中

方法调用完毕,Cat类和eat方法消失

Cat c 被加载到main方法中

因为这时a的地址值原本就是001,指向地址值为001的cat

这时我们吧001 也给到 Cat c

这时调用方法就相当于调用001 Cat中的

这时我们向上转型狗 dog 两者为继承关系,所以成立,在堆内存空间中创建一个new Dog() 地址值为002的空间 同时a的地址值变为002

编译看左边,执行看右边,右边是Dog,所以去Dog中找eat方法,输出

这时我们再向下转型,这时候a 的地址值002 指向 狗,左边是猫,右边是狗,

虽然猫狗都继承自动物,但是彼此并不相等,如果强制执行,就会产生ClassCastException(类型转换异常)

暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇