Java--多态

什么是多态?如何在Java中实现多态? 多态(Polymorphism)是面向对象编程(OOP)的核心概念之一。它指的是一个接口或基类可以有多种不同的实现方式,程序在运行时可以动态地选择具体的实现方法。多态性允许对象以多种形式表现,从而使得代码更加灵活和可扩展。编译时多态性(静态多态性):通过方法重载(Method Overloading)实现。运行时多态性(动态多态性):通过方法重写(Method Overriding)和接口实现。多态是Java面向对象编程的重要特性,通过方法重载实现编译时多态性,通过方法重写和接口实现运行时多态性。 阅读详情

在理解多态前要先知道什么时向上转型,方法重写

向上转型:

向上转型:实际就是创建一个子类对象,将其当成父类对象来使用。
语法格式:父类类型 对象名 = new 子类类型()

例如:

已经创建了狗类和动物类,狗类继承了动物类

Animal animal = new Dog();

animal是父类类型,但可以引用一个子类对象,因为是从小范围向大范围的转换。 

 也可以作为方法传参的接受值

public class Test {
    public static void func(Animal animal){
        animal.eat();
    }
    public static void main(String[] args) {
        Dog dog = new Dog();
        func(dog);
    }
}

也可以作为方法的返回值 

public class Test {
    public static Animal func(Animal animal){
        animal.eat();
        return null;
    }
    public static void main(String[] args) {
        Dog dog = new Dog();
        func(dog);
    }
}

向上转型的优点:让代码实现更简单灵活。
向上转型的缺陷:不能调用到子类特有的方法。 

方法重写:

重写(override):也称为覆盖。重写是子类对父类非静态、非private修饰,非final修饰,非构造方法等的实现过程进行重新编写, 返回值和形参都不能改变。即外壳不变,核心重写!重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

【方法重写的规则】
子类在重写父类的方法时,一般必须与父类方法原型一致: 返回值类型 方法名 (参数列表) 要完全一致
被重写的方法返回值类型可以不同,但是必须是具有父子关系的
访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类方法被public修饰,则子类中重写该方法就不能用protected修饰
父类被static、private修饰的方法、构造方法都不能被重写。
重写的方法, 可以使用 @Override 注解来显式指定. 有了这个注解能帮我们进行一些合法性校验. 例如不小心将方法名字拼写错了 (比如写成 aet), 那么此时编译器就会发现父类中没有 aet 方法, 就会编译报错, 提示无法构成重写. 

 

class Animal{
    public String name;
    public int age;
    public void eat(){
        System.out.println(this.name + "正在吃东西");
    }
}
class Bird extends Animal{
    //重写eat
    @Override
    public void eat() {
        System.out.println(this.name + "正在吃虫子");
    }
}
class Dog extends Animal{
    //重写eat
    @Override
    public void eat() {
        System.out.println(this.name + "正在吃骨头");
    }
}

Bird类和Dog类重写了父类Animal中的eat方法

以上都是为多态来做准备的

多态:

什么是多态?

就是去完成某个行为,当不同的对象去完成时会产生出不同 的状态。

比如鸟和狗吃饭,鸟吃的是虫子,狗吃的是骨头

Java中怎么实多态呢? 这里就要用到上述的两种方法,向上转型和方法重写

在java中要实现多态,必须要满足如下几个条件,缺一不可:
1. 必须在继承体系下
2. 子类必须要对父类中方法进行重写
3. 通过父类的引用调用重写的方法

class Animal{
    public String name;
    public int age;
    public void eat(){
        System.out.println(this.name + "正在吃东西");
    }
}
class Bird extends Animal{
    //重写eat
    @Override
    public void eat() {
        System.out.println(this.name + "正在吃虫子");
    }
}
class Dog extends Animal{
    //重写eat
    @Override
    public void eat() {
        System.out.println(this.name + "正在吃骨头");
    }
}
public class Test {
    public static void func(Animal animal){
        animal.eat();
    }
    public static void main(String[] args) {
        Dog dog = new Dog();
        dog.name = "二哈";
        Bird bird = new Bird();
        bird.name = "叽叽";
        func(dog);
        func(bird);
    }
}

 

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

这里还有一个疑问明明是animal调用的eat为啥不执行父类的eat呢?

之里面其实发生了动态绑定在编译的时候确实是调用的animal的eat但是在运行时animal这个引用的地址被改为了dog或cat这个引用的地址,发生了动态绑定,所以就执行了cat或dog的eat

再来看一个多态的实例:

画图形

class Shape{
    public void draw(){
        System.out.println("画一个图形");
    }
}
class Cycle extends Shape{
    @Override
    public void draw() {
        System.out.println("画一个原圆");
    }
}
class Rect extends Shape{
    @Override
    public void draw() {
        System.out.println("画一个矩形");
    }
}
class Triangle extends Shape{
    @Override
    public void draw() {
        System.out.println("画一个三角形");
    }
}
public class Test2 {
    public static void main(String[] args) {
        Cycle cycle = new Cycle();
        Rect rect = new Rect();
        Triangle triangle = new Triangle();
        Shape[] shapes = {cycle, cycle, rect,rect,triangle,triangle};
        for(Shape shape : shapes){
            shape.draw();
        }
    }
}

那多态的优点是什么呢?

拿上面代码举例

如果不用多态完成又能写成什么样子呢?

class Shape{
    public void draw(){
        System.out.println("画一个图形");
    }
}
class Cycle extends Shape{
    @Override
    public void draw() {
        System.out.println("画一个原圆");
    }
}
class Rect extends Shape{
    @Override
    public void draw() {
        System.out.println("画一个矩形");
    }
}
class Triangle extends Shape{
    @Override
    public void draw() {
        System.out.println("画一个三角形");
    }
}
public class Test2 {
    public static void main(String[] args) {
        Cycle cycle = new Cycle();
        Rect rect = new Rect();
        Triangle triangle = new Triangle();
        String[] strings = {"cycle","cycle", "react", "react","triangle","triangle"};
        for(String s : strings){
            if(s.equals(cycle)){
                cycle.draw();
            }else if(s.equals(rect)){
                rect.draw();
            }else{
                triangle.draw();
            }
        }
    }
}

在main函数中存在着大量的if else语句复杂度很高

所以多态的优点:

1. 能够降低代码的 "圈复杂度", 避免使用大量的 if - else
什么叫 "圈复杂度" ?
圈复杂度是一种描述一段代码复杂程度的方式. 一段代码如果平铺直叙, 那么就比较简单容易理解. 而如果有很多的条件分支或者循环语句, 就认为理解起来更复杂.
因此我们可以简单粗暴的计算一段代码中条件语句和循环语句出现的个数, 这个个数就称为 "圈复杂度".如果一个方法的圈复杂度太高, 就需要考虑重构.

2. 可扩展能力更强
如果要新增一种新的形状, 使用多态的方式代码改动成本也比较低.(这里就不做展示了)

缺点:

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

对于第二点缺点 看下面代码的输出结果是什么 num的值是多少

class A{
    public void func(){
        System.out.println("调用了A");
    }
    public A() {
        func();
    }
}
class B extends A{
    private int num = 1;

    @Override
    public void func() {
        System.out.println("调用了B  " + num);
    }
}
public class Test3 {
    public static void main(String[] args) {
        B b = new B();
    }
}

结果↓

结果为0 明明初始化为1了 为何输出的时0

其实:

构造 B 对象的同时, 会调用 A 的构造方法.
A 的构造方法中调用了 func 方法, 此时会触发动态绑定, 会调用到 B 中的 func
此时 B 对象自身还没有构造, 此时 num 处在未初始化的状态,

所以:

尽量不要在构造器中调用方法(如果这个方法被子类重写, 就会触
发动态绑定, 但是此时子类对象还没构造完成), 可能会出现一些隐藏的但是又极难发现的问题.

 

【一】PCIe基础知识 Linux PCIe基础知识 阅读详情

相关推荐

地震数据可视化必备:5分钟读懂SEGY道头字段全解析(含坐标定位指南)

本文深入解析了SEGY文件格式中道头坐标字段的提取与可视化方法。针对地震数据处理中的常见痛点,详细介绍了sx/sy、gx/gy等关键坐标字段的二进制解析、比例因子应用、单位转换及常见问题解决方案,并提供了实用的Python代码示例,帮助开发者实现从SEGY文件到三维空间可视化的完整流程。

echo99的专栏 1010

Java中编译时多态与运行时多态

文章目录1. 什么是多态2. 编译时多态3. 运行时多态总结Reference 口诀:成员变量,静态方法看左边;非静态方法:编译看左边,运行看右边 当父类变量引用子类对象时(Father f = new Son();),在这个引用变量f指向的对象中,它的成员变量和静态方法与父类是一致的,他的非静态方法,在编译时是与父类一致的,运行时却与子类一致(发生了复写) 1. 什么是多态 多态是指允许不同子类型的对象对同一行为作出不同的响应。例如在生活中,比如跑的动作,小猫、小狗和大象,跑起来是不一样的。再比如飞

xylitolz的博客 9380

Excel曲线拟合实战:从基础趋势线到高级回归分析

本文系统介绍了Excel曲线拟合的完整工作流,从基础的散点图与趋势线应用,到利用Solver插件进行自定义高级回归分析。文章详细讲解了线性、多项式、指数、对数等六大常用数学模型的适用场景与选择方法,并强调了通过R²值、残差图评估拟合效果、避免过拟合与外推风险的关键步骤,帮助读者掌握从数据探索到预测评估的实战技能。

weixin_29280219的博客 532

Java多态性:Java什么是多态?

多态性是面向对象编程的又一个重要特征,它是指在父类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为,这使得同一个属性或方法在父类及其各个子类中具有不同的含义。 对面向对象来说,多态分为编译时多态和运行时多态。其中编译时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的方法。通过编译之后会变成两个不同的方法,在运行时谈不上多态。而运行时多态是动态的,它是通...

jijiangpeng的博客 5548

【DIY】使用STM32及PID算法实现一个磁悬浮玩具

今天教大家来做一个磁悬浮玩具。

小白白学电子 1万+

XGBoost原生接口和Sklearn接口参数详解

XGBoost原生接口和Sklearn接口参数详解

算法工程师 2654

Java的多态

Java多态是面向对象编程的核心特性,包括编译时多态和运行时多态。

2401_84284464的博客 1157

【附代码】SSVEP解码算法 - 扩展典型相关分析(eCCA)

本文主要对SSVEP解码算法-eCCA进行复现和测试。本文提供程序的所有代码,只要在Matlab上即可运行。读者可以根据程序自主调整,方便学习以及初学者更好地了解SSVEP的经典算法。

计算机小白 1334

Java中多态

目录 1、概述 2、多态的定义与使用格式 3、多态的特点 4、多态成员的特点 5、instanceof 关键字 6、多态转型 7、多态的优缺点 1、概述 多态就是描述一个事物的多种形态,如小明是一个学生,他既是人,也是学生,出现两种形态。Java中多态的代码体现在一个子类对象(实现类对象)既可以给这个子类(实现类对象)引用变量赋值,又可以给这个子类(实现类对象)的父类(接口)变...

ONESTARの博客 4285

57、振荡扫描仪的挠性枢轴:原理、设计与材料选择

本文深入探讨了振荡扫描仪中挠性枢轴的工作原理、设计方法与材料选择。挠性枢轴因其无润滑、高精度、低周期性误差和潜在无限寿命等优势,广泛应用于光学、太空、医学和半导体等领域。文章分析了其在小角度下的优异性能与无法连续旋转等局限性,提供了关键设计公式,并对比了多种挠性材料的性能指标。同时,结合不同应用场景提出设计优化策略,并展望了微型化、智能化和高性能材料等未来发展趋势,为工程实践提供了系统的设计流程与选型建议。

numpy6sculptor的博客 95

如何理解下一代ERP 即:华为MetaERP

如何理解下一代ERP 即:华为MetaERP 华为的 MetaERP核心定位: 华为MetaERP是华为公司自主研发的下一代企业核心商业管理系统。它不仅仅是一个传统的ERP(企业资源规划)系统,更是一个面向未来、基于云原生、AI驱动、安全可信的企业核心管理平台。

金牌架构师 1142

Java 多态以及多态的实现

编译环境 windows 10 JDK 1.8 eclipse 目录    一、多态的基本概念    二、继承    三、多态的实现    四、多态存在的三个必要条件    五、重写    六、抽象类和抽象方法    七、接口    八、向上转型实现多态    九、多态的优缺点 前言   多态,多态,多态到底是一个什么样的定义呢,充满着好奇心,决定去研究一番。 多态(Polymorphism)的基本概念   多态意味着父类的变量可以指向子类对象。多态是同一个行为具有多个不同表现形式或形态的能力,就

Karbob 2447

【Dify】知识库智能检索应用

本文介绍了一个基于大语言模型的知识库检索系统,实现从自然语言提问到智能回答的自动化流程。该系统通过知识检索节点定位相关信息,利用重排序模型优化结果,最后由大语言模型生成自然语言答案。核心模型包括InternLM2-7B和BCE重排序模型。工作流程包含输入问题、检索重排序、智能生成和答案输出四个阶段,适用于企业知识管理、客户支持、教育培训等多种场景,能显著提升信息检索效率和准确性。文章还提供了相关开发文档链接,涵盖AIGC工具平台搭建、常见问题解决等内容。

Mr数据杨 1000

java的多态

java的多态

听海边涛声 806

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

什么是Java多态?如何实现Java多态?

java多态这个概念在同学们深入学习java的时候就会被提出,很多同学并不知道是什么意思,如何实现。今天小千就来给大家介绍一下什么是java多态和java如何实现多态。 什么是多态? 指允许不同类的对象对同一消息做出响应。即同一消息可以根据发送对象的不同而采用多种不同的行为方式。(发送消息就是函数调用) 实现多态的技术称为:动态绑定(dynamic binding),是指在执行期间判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。 多态的作用:消除类型之间的耦合关系。 现实中,关于多态的例子不胜

xiaoxijinger的博客 6219

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Java基础之Java的多态

在本文中,我们深入探讨了Java多态性的概念、实现方式以及它在面向对象编程中的重要性。多态性是Java语言的核心特性之一,它允许我们通过父类引用调用子类的方法,从而增强了代码的灵活性和可扩展性。我们学习了多态的两种类型:编译时多态和运行时多态,以及它们在实际编程中的应用。编译时多态主要通过方法重载和重写实现,而运行时多态则依赖于继承和方法重写。同时,我们也指出了多态的一些限制,例如无法访问子类特有的方法和属性。

daadaddc的博客 2310

WINCC7.3破解文件

WINCC7.3硬件够破解文件,有需要的下载!WINCC7.3硬件够破解文件,有需要的下载!

Java中的多态:什么是多态?

Java中的多态:什么是多态? 多态性是面向对象编程的三大重要特征之一,它是指在父类中定义的属性和方法被子类继承之后,可以具有不同的数据类型或表现出不同的行为,这使得同一个属性或方法在父类及其各个子类中具有不同的含义。 对面向对象来说,多态分为编译时多态和运行时多态。 其中编译时多态是静态的,主要是指方法的重载,它是根据参数列表的不同来区分不同的方法。通过编译之后会变成两个不同的方法,在运行时谈不上多态。而运行时多态是动态的,它是通过动态绑定来实现的,也就是大家通常所说的多态性。 Java实现多态有 3

java领域分享 9728

Java中关于多态的总结

多态(Polymorphism)指同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。

2301_80391652的博客 938

java之多态

java多态

DJQ351044djqDJQ的博客 1143

Java多态

Java中的多态(Polymorphism)是面向对象编程的三大特性之一,另外两个是封装(Encapsulation)和继承(Inheritance)。多态意味着“多种形态”,它允许我们以统一的方式处理不同类型的对象。在Java中,多态主要通过方法的重写(Overriding)和方法的重载(Overloading)来实现,但通常我们说的多态是指方法的重写和通过父类引用指向子类对象。

zgw555555的专栏 1050

Java 多态

对象的多态性允许我们编写更加灵活和可扩展的代码。通过继承和接口,我们可以设计出能够以统一的方式处理不同对象的系统。多态性是面向对象设计中实现“开闭原则”(对扩展开放,对修改封闭)的关键技术之一。向上转型:子类对象转为父类类型,是自动且安全的,但访问范围受限于父类。向下转型:父类对象转为子类类型,需要显式转换且要确保类型安全,可以访问子类特有属性和方法。

y123916的博客 1387

java动态多态_Java动态多态原理

很多书本说到多态,概念就把人看晕了,本人从实际使用角度,来介绍多态,希望对大家有用。什么是多态:多态简单来说,就是调用同一个函数名字,会出现不同的运行结果。多态分为几种:多态分为静态多态、动态多态什么是静态多态静态多态性指的是程序在编译时,系统就能决定调用哪个函数,一般指的是重载,是在一个类中的行为。重载,就是在类中创建多个方法,它们具有相同的名字,但具有不同的参数和不同的定义。调用方法时通过传递...

weixin_39881167的博客 933

java的两种多态

     1. Java中除了static和final方法外,其他所有的方法都是运行时绑定的。private方法都被隐式指定为final的,因此final的方法不会在运行时绑定。当在派生类中重写基类中static、final、或private方法时,实质上是创建了一个新的方法。     2.在派生类中,对于基类中的private方法,最好采用不同的名字。     3.包含抽象方法的类叫做抽

JavaTiger 4595

多态 java_什么是java多态?java多态的使用

本篇文章给大家带来的内容是什么是java多态?java多态的使用,通过游戏中的一些功能带你掌握多态的使用。下面由动力节点java学院小编为大家一一介绍什么是java多态及java多态的使用。希望对大家有帮助。为什么要使用多态在一款对战类游戏中(如有雷同纯属巧合),有两个不同的法师英雄:小乔、妲己。两个法师英雄的都有攻击的方法,小乔的攻击伤害为10,消耗魔法20。妲己的攻击伤害为15,消耗魔法30。...

weixin_31049801的博客 740

java中多态_java之多态

1.多态的概述:是面向对象的三大特性之一,封装、继承、多态。①一个具体的对象有多种形态,老虎既属于猫科动物(因为子父类是相对的,所以猫科动物也可以看做子类),又属于哺乳动物,所以老虎既可以拥有猫科动物的属性,又有哺乳动物的属性。②Java中多态的代码体现在一个子类对象(实现类对象)既可以给这个子类(实现类对象)引用变量赋值,又可以给这个子类(实现类对象)的父类(接口)变量赋值。普通类与普通类,抽象...

weixin_36457551的博客 3717
上一篇: Java语法--继承
下一篇: Java语法:抽象类和接口
刘 大 望
博客等级 码龄2年 896粉丝 61原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值