当前位置: 首页 > news >正文

Java 三大特性—多态

目录

  • 1、多态的概念
  • 2、多态的条件
  • 3、向上转型
    • 3.1 概念
    • 3.2 使用场景
  • 4、向下转型
  • 5、多态的优缺点

1、多态的概念

多态,通俗来讲就是多种形态,即对于同样的行为,不同的对象去完成会产生不同的状态。比如动物都会吃东西,小狗和小猫都是动物,但是小狗是吃狗粮,而小猫是吃猫粮。

在这里插入图片描述

2、多态的条件

在 Java 中实现多态需要满足下述条件,缺一不可:

  1. 必须在继承体系下。
  2. 子类对基类的方法实现重写(即方法原型相同,但实现体不同)。
  3. 通过基类的引用调用重写的方法。

多态的体现:在代码运行时,当传递不同类的对象时,会调用对应类中的方法。

举例说明:Animal 类是父类,Dog 类和 Cat 类是子类,继承自 Animal 类,同时 Dog 类和 Cat 类对 Animal 类的方法进行了重写。

// 父类
public class Animal {
    protected String name;
    protected int age;

    public Animal(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public void eat(){
        System.out.println(name + "在吃饭");
    }

    public void bark(){
        System.out.println(name + "在大叫");
    }
}

// Dog 类:继承自 Animal 类
// 1. 在继承体系中
public class Dog extends Animal{
    protected String color;

    public Dog(String name, int age, String color) {
        super(name, age);
        this.color = color;
    }

    // 2. 对父类方法进行重写
    @Override
    public void eat() {
        System.out.println(name + "在吃狗粮");
    }

    @Override
    public void bark() {
        System.out.println(name + "汪汪汪~");
    }

	public void sleep(){
        System.out.println(name + "在睡觉");
    }
}

// Cat 类:继承自 Animal 类
// 1. 在继承体系下
public class Cat extends Animal {
    protected String temper;

    public Cat(String name, int age, String temper) {
        super(name, age);
        this.temper = temper;
    }

    // 2. 对父类方法进行重写
    @Override
    public void eat() {
        System.out.println(name + "在吃猫粮");
    }

    @Override
    public void bark() {
        System.out.println(name + "喵喵喵~");
    }
	
	public void drink(){
        System.out.println(name + "在喝水");
    }
}

根据上述类,利用 Animal 类的引用调用被重写的方法从而实现多态。

public class Test {
    public static void method(Animal animal){
        // 3. 通过基类的引用调用被重写的方法
        // 在 method() 方法中利用 Animal 对象的引用调用被重写的方法
        // 在程序的编译阶段并不知道会调用哪个子类的对象所对应的方法
        // 只有在运行阶段给 method() 方法传参时才知道。
        animal.eat();
        animal.bark();
    }

    public static void main(String[] args) {
        Dog dog = new Dog("毛毛", 5, "白色");
        method(dog);

        Cat cat = new Cat("小七", 1, "乖巧");
        method(cat);
    }
}

运行结果:

在这里插入图片描述
由上述代码可知,虽然在 main 方法中调用的是同一个 method() 方法,但是运行的结果却不同。这是因为 Animal 类是 Dog 类和 Cat 类的基类,基类可以引用不同子类的对象,因此传递给形参 animal的值会出现不同,当传递的是 Dog 类的对象时,会调用 Dog 类中的方法,当传递的是 Cat 类的对象时,会调用 Cat 类中的方法。
当程序员在编写 method() 方法时并不知道也不关心形参 animal 指的是 Cat 类还是 Dog 类的对象,只有当代码运行起来,实参传递给形参值的时候才知道。形参 animal 调用方法会有不同的表现,这种行为就称作多态。

3、向上转型

3.1 概念

向上转型,实际上是创建一个子类对象,当作父类对象来使用。

Animal animal = new Dog(“毛毛”, 5, “白色”);

animal 是父类类型,可以引用子类对象,因为狗和猫都是动物,这是从小范围到大范围的转换,是安全的。但是向上转型之后,无法通过父类的引用调用子类新增的成员方法。

在这里插入图片描述

3.2 使用场景

向上转型有以下三种使用场景:

  1. 直接赋值:子类对象赋值给父类对象。
Animal animal = new Dog("毛毛", 5, "白色");
  1. 方法传参:形参为父类型引用,可以接收任意子类的对象。
public class Test {
	// 将 Dog 类和 Cat 类对象的引用传参给 Animal 类的引用
    public static void method(Animal animal){
        animal.eat();
        animal.bark();
    }

    public static void main(String[] args) {
        Dog dog = new Dog("毛毛", 5, "白色");
        method(dog);
        Cat cat = new Cat("小七", 1, "乖巧");
        method(cat);
    }
}
  1. 方法返回:方法返回类型是父类类型,可以返回任意子类对象。
    public Animal buyCat(){
    	// 创建 cat 对象并返回
        Cat cat = new Cat("小七", 1, "乖巧");
        return cat;
    }

4、向下转型

将子类对象转换为父类时,会无法调用子类中特有的方法,但是有时候需要调用,那么此时将父类引用还原为子类对象即可,即向下转换。

    public static void main(String[] args) {
        Animal animal = new Dog("毛毛", 5, "白色");
        // 将 Animal 类型对象强转为 Dog 类型,此时可以调用 sleep() 方法
        Dog dog = (Dog) animal;
        dog.sleep();
    }

但是向下转型很容易出现问题。

在这里插入图片描述
Java 中为了提高向下转型的安全性,引入了 instanceof。

instanceof 类名N:实际引用的是否为 N 类的对象,如果是返回true,否则返回false

如果该表达式为真,则可以安全转换,否则不能进行安全转换。

	public static void main(String[] args) {
	    Dog dog = new Dog("毛毛", 5, "白色");
	    Cat cat = new Cat("小七", 1, "乖巧");
	    Animal animal = cat;
	    animal = dog; // 此时 animal 实际指向的是 Dog 类的对象
	    if(animal instanceof Cat){
	        cat = (Cat)animal;
	        cat.drink();
	    }
	    if(animal instanceof Dog){
	        dog = (Dog)animal;
	        dog.sleep();
	    }
	}

运行结果:

在这里插入图片描述
由上述结果可知,由于 animal 实际指向的是 Dog 类的对象,因此执行第二个 if 语句块,将 animal 强转为 Dog 类型对象,此时就可以调用 Dog 类中新增的成员方法。

5、多态的优缺点

【优点】

  1. 降低代码的“圈复杂度”,即避免大量使用 if-else。
  2. 可扩展能力更强。

【缺点】

  1. 代码的运行效率降低。
  2. 属性没有多态性:当子类和父类有同名属性时,通过父类引用,只能引用父类自己的成员属性。
  3. 构造方法没有多态性。

相关文章:

  • 海外直播平台交互设计师简历模板
  • 【PVR Review】《Review of Deep Learning Methods for Palm Vein Recognition》
  • 新HTML5
  • 4.3-1 jenkins安装
  • 全国大学生数学建模竞赛赛题深度分析报告(2010-2024)
  • MySQL学习笔记(四)——DML和DQL
  • 智能手表该存什么音频和文本?场景化存储指南
  • 《算法笔记》10.3小节——图算法专题->图的遍历 问题 B: 连通图
  • 测开八股收集
  • 【C++编程基础-关键字】:define和inline的区别
  • 在 Ubuntu 下通过 Docker 部署 PSQL 服务器的详细技术博客
  • codeforces B. Large Array and Segments
  • 【漫话机器学习系列】184.正态分布(Normal Distribution)
  • 青少年编程与数学 02-015 大学数学知识点 05课题、优化理论
  • zk源码—2.通信协议和客户端原理二
  • QML和C++交互
  • 压测工具开发实战篇(四)——client子窗口功能
  • 高德地图 3D 渲染-区域纹理图添加
  • IntelliJ IDEA 中通义灵码插件使用指南
  • 【从0到1学MybatisPlus】MybatisPlus入门
  • 云南旅游市场10条措施征求意见:对强制诱导购物等吊销导游证的不得再次核发
  • “宝马女司机驾车拖行虐猫”引关注,海口警方介入调查
  • 国家发改委谈稳定外资:将研究制定鼓励外资企业境内再投资政策措施
  • 英伟达回应在上海设立新办公空间:正租用一个新办公空间,这是在中国持续深耕的努力
  • 台陆委会将欧阳娜娜等20多名艺人列入重要查核对象,国台办回应
  • 全总联合六部门印发工作指引,共保劳动者合法权益