栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

java的多态到底是什么?(详细案例逐步分析)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

java的多态到底是什么?(详细案例逐步分析)

java的多态到底是什么?(详细案例逐步分析)

文章目录

java的多态到底是什么?(详细案例逐步分析)

概念前提引入

向上转型向下转型instanceof 运算符

使用说明注意:好处: 基础语法

多态语法实例案例—为什么要用 if instanceof ?

概念

多态,简单来说就是一种事物的多种形态。在java中即指一个实体在不同时刻代表的对象可能不一样。

原因在与对象都是引用数据类型。可以理解为父类型的引用指向了子类型的对象,或者是接口的引用指向接口实现类的对象。

举一个栗子,当你考试的时候有一个问题让你随便写一个动物的名字,此时,你写熊猫也好,长颈鹿也罢,只要它属于动物就行,这就是最基本的“多态”。再进一步,这些动物都要进食,我们就可以把进食设置为一个方法,但是每种动物的进食方法不一样,那这个就可以设置每个动物进食的特征。这样当我们说的动物不相同的时候,虽然使用了所有动物的特性——进食,但是又能把进食这个行为描述的更具体。

前提引入 向上转型

子 —> 父(自动类型转换)

向下转型

父 —> 子(强制类型转换,需要加强制类型转换符)

不要随便做强制类型转换。
当你需要访问的是子类对象中“特有”的方法,此时必须进行向下转型

instanceof 运算符 使用说明

第一:instanceof可以在运行阶段动态判断引用指向的对象的类型。
第二:instanceof的语法:
(引用 instanceof 类型)
第三:instanceof运算符的运算结果只能是:true/false
第四:a是一个引用,a变量保存了内存地址指向了堆中的对象。
假设(a instanceof A)为true表示:
a引用指向的堆内存中的java对象是一个A
false表示:
a引用指向的堆内存中的java对象不是一个A

注意:

任何时间,对类型进行向下转型时,一定要使用
instanceof 运算符进行判断

好处:

使用该关键字都可以避免ClassCastException异常

基础语法

1、包括编译阶段和运行阶段:

编译阶段:绑定父类的方法。
运行阶段:动态绑定子类型对象的方法。

简单来说就是编译阶段的类型是父类的,但是实际在运行的时候最终调用了子类的方法

也可以理解为:

多态表示多种形态:
编译的时候一种形态。
运行的时候另一种形态。

2、易错点:

多态情况下,子父类存在同名的成员变量或者静态成员方法的时候,访问的都是父类成员的变量或者方法

存在==同名的非静态的成员方法==的时候,访问的是==子类==的成员方法

3、使用场景

有继承关系 满足 is a ;例如:A is a B!

有实现关系 满足 has a ;例如:A has a B!

有方法的覆盖

4、好处

提高程序的扩展性

降低程序的耦合度

可以将所有的对象都看做是父类的,进而屏蔽了不同子类对象之间的差异性

多态语法实例
package com.blog;



public class Test{
    public static void main(String[] args) {
        //之前创建对象
        Animal animal01 = new Animal();
        Cat cat01 = new Cat();
        Dog dog01 = new Dog();
        Pig pig01 = new Pig();

        //学了多态以后创建对象 为什么可以这样? 因为有继承关系,满足 is a
        //切记,是父类型的引用    指向  子类型的对象
        Animal a1 = new Cat();
        Animal a2 = new Pig();

        //能不能这样呢?不可以 为什么?因为二者没有继承关系 is a虽然说的通,但是有继承关系这个前提不满足
        //Animal a3 = new Dog();

        
        //此时创建一个Animal对象,底层实际上是一只猫咪
        Animal a4 = new Cat();
        //调用子类继承过来的方法会是什么结果呢?执行子类重写的方法
        a4.eat();//猫咪在吃鱼!
        

        // 那么能否调用猫咪独有的方法呢? 不能!
        //a4.fish(); 报错了,为什么?这个引用不是实际指向了cat对象吗?为什么不能调用呢?
        

        //那么怎么调用猫咪独有的方法呢?   向下转型
        Cat newCat = (Cat) a4;
        

        Pig newPig = (Pig) a4;
        newPig.sleep();

        //怎么避免这类异常呢?
        //instanceof关键字
        if(a4 instanceof Pig){
            //进来了说明a4就是一个猪猪类型的对象
            Pig realPig = (Pig) a4;
        }
    }
}


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


class Pig extends Animal {
    @Override
    
    public void eat() {
        System.out.println("猪猪在吃白菜!");
    }
    
    public void sleep(){
        System.out.println("猪猪在睡觉!");
    }
}


class Cat extends Animal {
    
    @Override
    public void eat() {
        System.out.println("猫咪在吃鱼!");
    }
    
    public void fish(){
        System.out.println("猫咪在捕鱼!");
    }
}


class Dog {
    
    public void play(){
        System.out.println("狗狗在摇尾巴!");
    }
}
案例—为什么要用 if instanceof ?
package com.blog;


public class instanceofTests {

    

    public static void main(String[] args) {
        test(new Cat());
        test(new Pig());
        test(new Dog());
        test(new Animal());
    }
    
    
    
    

    
    static void test(Animal animal){

        if(animal instanceof Cat){
            ((Cat) animal).fish();
        }else if(animal instanceof Dog){
            ((Dog) animal).play();
        }else if(animal instanceof Pig){
            ((Pig) animal).sleep();
        }else {
            animal.eat();
        }

    }
}

class Animal{
    public void eat(){
        System.out.println("动物在吃东西!");
    }
}
class Dog extends Animal{
    @Override
    public void eat(){
        System.out.println("狗狗在啃骨头!");
    }
    public void play(){
        System.out.println("狗狗在摇尾巴!");
    }
}
class Pig extends Animal{
    @Override
    public void eat() {
        System.out.println("猪猪在吃白菜!");
    }
    public void sleep(){
        System.out.println("猪猪在睡觉!");
    }
}
class Cat extends Animal{
    @Override
    public void eat() {
        System.out.println("猫咪在吃鱼!");
    }
    public void fish(){
        System.out.println("猫咪在捕鱼!");
    }
}

以上均为本人个人观点,借此分享。如有不慎之处,劳请各位批评指正!鄙人将不胜感激并在第一时间进行修改!

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/778305.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号