Java三兄弟之多态

本文介绍了Java的多态特性,包括多态的形式、执行过程、优点,以及多态在成员变量、方法参数、数组和返回值类型中的应用。同时讨论了向上转型和向下转型的概念,强调了类型转换在面向对象编程中的重要性。
摘要由CSDN通过智能技术生成

Java的三大特征:封装、继承、多态

大哥:封装
二哥:继承

插入一个知识点

对象数组

数组是我们经常使用的一个数据容器,像我们之前使用int[]、char[]等。这些大都是基本数据类型的数组,除了这些我们还可以创建对象的数组,之前我们使用过的int[][]就是一种。元素是对象的数组就是对象数组。

注意:对象数组,首先要创建数组对象本身,即确定数组的长度,然后再创建每一个元素对象,如果不创建,数组的元素的默认值就是null,所以很容易出现空指针异常NullPointerException。

  1. 对象数组的内存图分析

    对象数组内存分析图

多态(polymorphism)

多态是继封装、继承之后,面向对象的第三大特性。也是面向对象思想的核心。

我们通过代码先看一个案例,引入多态性这个重要特性。

定义一个Animal类

public class Animal {
   
    //String name = "animal";
    public void eat(){
   
        System.out.println("动物吃饭");
    }
}

定义一个Dog类

public class Dog extends Animal {
   //继承Animal类
    //String name = "dog";
    @Override
    public void eat() {
   
        System.out.println("狗啃骨头");
    }

}

定义一个Person类

public class Person {
   
    //喂狗吃饭
   public void feed(Dog dog){
   
        dog.eat();
    }
}

测试类

public class Test1 {
   
    public static void main(String[] args) {
   
        Person p=new Person();
        //测试人喂狗吃饭
        p.feed(new Dog());
    }
}

这时如果需要拓展功能,增加一个猫Cat类,让人喂Cat吃饭,应该如何做?

很简单,在Person类中增加喂猫的方法,那如果后期还要不断的增加新功能(新增各种动物类),就要不断增加Person类对应的方法。这里就出现了一个问题:违背了软件开发中的开闭原则(对修改关闭,对扩展开放),并且大量类同代码冗余,即每次新增的方法除了参数类型不同,其他都基本相同。

能不能用简单方式解决?

只需要在Person类中定义一个类似的方法,参数为Animal,其他全舍去,这就是多态的应用。

//修改后的Person类
public class Person {
   
    //喂动物吃饭
   public void feed(Animal animal){
   
        animal.eat();
    }
}

再次测试,功能正常,增加新的动物类测试,发现不需要修改Person类,功能依然正常。

帮助理解:狗和猫统称为动物

什么是多态

就像液体在不同的温度下呈现不同的状态一样。Java的多态也是指在不同的子类下,父类里面被子类重写的方法也会有不同的功能。

1、多态的形式

Java规定父类类型的引用变量可以接收子类类型的对象。这里父子类是相对的,有直系亲属的。

格式:

父类类型 变量名 = 子类对象;

父类类型:指子类继承的父类类型,或者实现的父接口类型。
所以说继承是多态的前提

例如:

//多态的引用形式
Animal a = new Cat();//Cat对象属于其父类Animal类型。
2、多态的执行过程

多态形式在执行的过程中:

  • 编译阶段会先在父类类型中查看是否有要调用的方法,如果有的话(子类重写了父类的这个方法)编译通过,如果没有的话编译不通过。
  • 编译过了之后在运行阶段会按照子类的方法去运行。

一句话概括了就是:编译看左边,运行看右边。

public class Test {
   
    public static void main(String[] args) {
   
        // 多态形式,创建对象
        Animal a = new Cat();  
        // 编译时,a变量呈现Animal类型特征,即Animal类中有eat方法,a调用eat方法时编译才能成功
        a.eat();//运行时,实际执行的是Cat类中重写的eat方法。 
        
        //a1.catchMouse();//错误,编译时左边父类Animal中没有此方法             
    }  
}
3、多态的优点

运行时,看“子类”,如果子类重写了方法,一定是执行子类重写的方法;变量引用的子类对象不同,执行的方法就不同,实现动态绑定。代码编写更灵活、功能更强大,可维护性和扩展性更好了。

  1. 提高程序的扩展性
  2. 降低类与类之间的耦合度

多态的应用形式

1、多态应用在成员变量和方法参数
  • 方法的形参是父类类型,调用方法的实参是子类对象
  • 实例变量声明父类类型,实际存储的是子类对象

代码如下:

public class OnePersonOnePet {
   
    private Pet pet;
    public void adopt(Pet pet) {
   //形参是父类类型,实参是子类对象
        this.pet = pet;
    }
    public void feed(){
   
        pet.eat();//pet实际引用的对象类型不同,执行的eat方法也不同
    
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

黑妖问路

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值