IT数码 购物 网址 头条 软件 日历 阅读 图书馆
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
图片批量下载器
↓批量下载图片,美女图库↓
图片自动播放器
↓图片自动播放器↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁
 
   -> Java知识库 -> 【开开心心学java,快快乐乐写代码】面向对象的三大特性之一:多态 -> 正文阅读

[Java知识库]【开开心心学java,快快乐乐写代码】面向对象的三大特性之一:多态

欢迎来到【开开心心学java,快快乐乐写代码】此专栏,本篇博客呢将会为大家仔细讲解关于面向对象的三大特性之一:多态。其他两大特性在我的主页里面也有,想了解的友友们欢迎垂阅。废话不多说,我们直接开始。放心,本博主依旧还是会讲的很仔细哒,认真看完,肯定会有所收获滴~

目录

1、 多态概念

2、多态的实现条件

2.1向上转型

2.2 动态绑定

3、 多态的优缺点


1、 多态概念

多态即不同类的对象调用同一方法时,根据对象的不同所表现出的行为不同

通俗一点的说法就是:同一个事件,发生在不同的对象上时,所表现出来的行为不同(这里的事件指方法)。比如动物都是吃东西,但猫吃猫粮,狗吃狗粮:


2、多态的实现条件

java中实现多态,必须满足以下几个条件缺一不可

  • 必须在继承体制下
  • 子类必须重写父类方法
  • 子类对象向上转型成父类引用,通过父类引用调用重写方法

也许现在看这几个条件还有点迷糊不理解。但是别担心,接下来我将用通俗的语言将这几个条件全部串起,带你理解是怎么用到这几个条件来体现多态的。继承和重写我之前都有写过相应博客,那向上转型又是什么呢,在这里我先讲一讲,,理解了向上转型,多态就不难理解啦。


2.1向上转型

向上转型:就是将子类对象当成父类对象使用,但是该对象就不能再调用子类中的特有成员。其语法格式为:父类类型 对象名=new 子类类型();

Animal? cat=new Cat( );//其中Animal是Cat的父类

cat是一个父类类型的引用,但是可以引用一个子类对象,因为是小范围转为大范围(创建一个猫,当做动物看待)。

请看以下代码,这里用到了向上转型:

public class Animal {
    String name;
    int age;

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

public class Cat extends Animal {
    public Cat(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println(this.name+"吃猫粮");
    }
}

public class Dog extends Animal {
    public Dog(String name, int age) {
        super(name, age);
    }

    @Override
    public void eat() {
        System.out.println(this.name+"吃狗粮");
    }
}

public class Test {
    public static void main(String[] args) {
        Animal cat=new Cat("咪咪",2);//这里发生向上转型
        Animal dog=new Dog("旺财",1);//向上转型

        //cat、dog为父类类型的引用
        cat.eat();
        dog.eat();

    }
}

输出结果:

在主函数里面,cat和dog都是父类类型的引用,分别都调用了父类中的eat()方法,但是最后所表现出的状态却不一样,在这里就体现了多态。

2.2 动态绑定

以上代码的输出结果可能有些人不太理解,明明调用的好像是父类中的eat()方法,但是最后表现出来的却像是调用子类的eat()方法呢?在这里其实发生了动态绑定。所谓动态绑定,引用究竟引用哪一个方法是在运行时才能确定的。在编译时不能确定(编译就能确定引用调用哪个方法的就静态绑定)。动态绑定经常发生在多态中,就像上面的代码一样。父类引用指向一个子类对象时,调用的函数是被子类重写过的函数时就会发生动态绑定,此时引用虽然调用的像是父类的方法,实际上最后调用的是子类重写父类方法后的方法

这就是由继承和向上转型所引发的多态,在下面再给大家仔细串一下发生多态整个过程

首先是在继承机制下,子类会重写父类的某些方法,然后定义一个父类类型的引用,这个引用指向了子类对象。当这个引用去调用父类中被子类重写了的方法时,就会发生动态绑定。最后调用的是子类中重写父类的方法


3、 多态的优缺点

优点1: 能够降低代码的“圈复杂度”,避免使用大量的if-else。

什么是圈复杂度?圈复杂度是一种描述代码复杂程度的方式。一段代码如果平铺直叙,就很容易理解,如果有大量的分支或循环,就认为理解起来较为复杂。

因此我们可以大致的计算一下一段代码中条件语句和循环语句中出现的个数,这个个数就称为圈复杂度。如果一个方法的圈复杂度太高,则一般要考虑重构。

不同公司对于代码的圈复杂度的规范不一样. 一般不会超过 10。

比如我们现在要打印多个图案,如果不用多态,则可以写成以下这个样子:

class Cycle{

    public void draw() {
        System.out.println("●");
    }
}
class  Triangle{

    public void draw() {
        System.out.println("△");
    }
}
class Flower{

    public void draw() {
        System.out.println("?");
    }
}
public class Test1 {
    public static void drawing(){
        Cycle cycle=new Cycle();
        Triangle triangle=new Triangle();
        Flower flower=new Flower();
        String[] shapes = {"cycle", "triangle", "flower"};
        for (String shape : shapes) {
            if (shape.equals("cycle")) {
                cycle.draw();
            } else if (shape.equals("triangle")) {
                triangle.draw();
            } else if (shape.equals("flower")) {
                flower.draw();
            }
        }
    }
    public static void main(String[] args) {
        drawing();
    }
}

运行结果:

如果用多态的思想来解决这个问题,则可以写成以下代码:

class A{
    public  void draw(){
        System.out.println("画东西");
    }
  
}
class Cycle extends A{

    @Override
    public void draw() {
        System.out.println("●");
    }
}
class  Triangle extends A{
    @Override
    public void draw() {
        System.out.println("△");
    }
}
class Flower extends A{
    @Override
    public void draw() {
        System.out.println("?");
    }
}
public class Test {
    public static  void func(A a){
        a.draw();

    }
    public static void main(String[] args) {

        A cycle=new Cycle();
        A triangle=new Triangle();
        A flower=new Flower();
        func(cycle);
        func(triangle);
        func(flower);
        cycle.funccc();
    }
}

运行结果:

?

很显然,两个代码实现的功能一样,但第二个代码使用多态来实现需求,使代码的可读性更高,简单明了,更易理解。

优点2:可扩展能力更强。如果我们想在以上的代码中增加一种需求,比如再画个☆,使用多态的方式来改动代码,成本会更低,只需要加入:

class FivePointedStar extends Shape {
????????@Override
????????public void draw() {
????????????????System.out.println("☆");
????????}
}

缺点:代码的运行效率降低


?以上就是我要今天分享的内容啦,后续我还会继续更新的哒,常看我的博客会学到很多知识哦?

  Java知识库 最新文章
计算距离春节还有多长时间
系统开发系列 之WebService(spring框架+ma
springBoot+Cache(自定义有效时间配置)
SpringBoot整合mybatis实现增删改查、分页查
spring教程
SpringBoot+Vue实现美食交流网站的设计与实
虚拟机内存结构以及虚拟机中销毁和新建对象
SpringMVC---原理
小李同学: Java如何按多个字段分组
打印票据--java
上一篇文章      下一篇文章      查看所有文章
加:2022-04-23 10:43:02  更:2022-04-23 10:43:09 
 
开发: C++知识库 Java知识库 JavaScript Python PHP知识库 人工智能 区块链 大数据 移动开发 嵌入式 开发工具 数据结构与算法 开发测试 游戏开发 网络协议 系统运维
教程: HTML教程 CSS教程 JavaScript教程 Go语言教程 JQuery教程 VUE教程 VUE3教程 Bootstrap教程 SQL数据库教程 C语言教程 C++教程 Java教程 Python教程 Python3教程 C#教程
数码: 电脑 笔记本 显卡 显示器 固态硬盘 硬盘 耳机 手机 iphone vivo oppo 小米 华为 单反 装机 图拉丁

360图书馆 购物 三丰科技 阅读网 日历 万年历 2024年11日历 -2024/11/24 5:08:08-

图片自动播放器
↓图片自动播放器↓
TxT小说阅读器
↓语音阅读,小说下载,古典文学↓
一键清除垃圾
↓轻轻一点,清除系统垃圾↓
图片批量下载器
↓批量下载图片,美女图库↓
  网站联系: qq:121756557 email:121756557@qq.com  IT数码