java之旅 (五)多态性

3、Java高级类设计:从OCA到OCP的进阶之旅 本文深入探讨了从OCA到OCP认证过程中Java高级类设计的核心概念,包括继承与组合、多态性、重写方法、静态关键字、抽象类和方法、final关键字、内部类、枚举类型以及接口的使用。通过详细示例和总结,帮助开发者掌握Java面向对象编程的高级技巧,提升代码复用性和可维护性,并为考试和实际开发提供坚实基础。 阅读详情

多态性是继数据抽象和继承后,面向对象语言的第三个特征。

 

绑定(binding)(看起来到像一个音译词):将方法的调用连到方法本身被称为绑定,当绑定发生在程序运行之前,被称做前绑定(earlybinding),而在程序运行的时候根据对象的类型来决定该绑定方法的成为后绑定,也叫运行时绑定(run-time binding)或动态绑定(dynamic binding);java的所有方法都采用后绑定,也就是说通常情况下,

你不用考虑是不是该采用后绑定,这一切都是自动的。

 

有一个经典的关于“形状”的例子,可以生动的说明什么是后绑定。

 

在这个例子中,基类是shape类,它有几个派生类:circle, Square, Triangle,

Shape s = new Circle();

这里先创建了一个Circle对象,接着把它给了一个Shape,看上去这样做有点不妥,不过确是不错的,因为Circle确实也是个Shape,接着假设你调用了一个基类的方法

     s.draw();

可能你会认为这次调用的应该是shape的draw方法吧,然而不是,它调用的却是circle的draw(),这就是因为实现的后绑定的原因。具体的实现方法就是基类定义了一个共用的接口――也就是说所有的shape都有draw()方法和erase()方法,派生类会覆写这两个方法从而提供不同的行为。到这里我想为什么不直接写成:

Circle s = new Circle();

s.draw();

后来看到作者将这个例子改动成随机的创建一个Circle, Square, Triangle对象,因为这时还不知道创建的对象具体是什么,所以只有像前面的那样的写法利用动态绑定才能实现。

      

       由此我们看到了多态性的最大优势:可扩展性。我们可以根据需要添加任意个新的类型,而不用担心修改基类里的方法,因此在一个设计良好的OOP程序里,绝大多数方法都会和draw()方法一样,只跟基类接口打交道。这种程序是可扩展的,因为你可以通过“让新的数据类型继承通用的基类“的方法来添加新的功能。而那些与基类接口打交道的方法,根本不需要做修改就能适应新的类。

 

       对程序员来说,多态性是一项非常重要的技术,它能让你将“会变的和不会变的分隔开来“。

 

抽象类和抽象方法:要创建像shape类这样的类对象是没有实际意义的,更何况你可能还要阻止用户这么做,这样我们可以使用抽象方法来解决这个问题。形如:

        abstract void f();

而包含一个或多个抽象方法的类就是抽象类(含有抽象方法是必须被定义位抽象类的),抽象类的作用是通过一个公共的接口来操控一组类。它的方法就像上面例子里基类的方法一样,只是样子货。而且如果创建一个抽象类的对象,编译器就会报错。

 

       如果你继承了抽象类,并打算创建该类的对象,那就必须实现基类所定义的全部方法,否则有一个抽象方法存在的话,那么该类还是个抽象类。

 

       创建一个不包含抽象方法的抽象类是可以的,这种技巧可以用于“不必创建抽象方法,但又想禁止别人创建这个类的对象的场合”。

 

       构造函数总是与众不同,牵涉到多态性也不例外。首先研究一个例子,复习一下构造函数的调用顺序先。

///////////////////////////////////////////////////////////////////////////////////

class Meal {
  Meal() { System.out.println("Meal()"); }
}
class Bread {
  Bread() { System.out.println("Bread()"); }
}
class Cheese {
  Cheese() { System.out.println("Cheese()"); }
}
class Lettuce {
  Lettuce() { System.out.println("Lettuce()"); }
}
class Lunch extends Meal {
  Lunch() { System.out.println("Lunch()"); }
}
class PortableLunch extends Lunch {
  PortableLunch() { System.out.println("PortableLunch()");}
}
 
public class Sandwich extends PortableLunch {
  private Bread b = new Bread();
  private Cheese c = new Cheese();
  private Lettuce l = new Lettuce();
  public Sandwich() {
    System.out.println("Sandwich()");
  }
  public static void main(String[] args) {
new Sandwich();
System.out.println("正确输出:");
    System.out.println(
      "Meal()/n"+
      "Lunch()/n"+
      "PortableLunch()/n"+
      "Bread()/n"+
      "Cheese()/n"+
      "Lettuce()/n"+
      "Sandwich()"
   );
  }
} 

///////////////////////////////////////////////////////////////////////////

也就是说复杂对象的构造函数的调用顺序是这样的:

1,  调用基类的构造函数。这是一个递归的过程,因此会先创建继承体系的根,然后是下一级派生类,以次类推直到最后一个继承类的构造函数。

2,  成员对象按照其声明的对象顺序进行初始化。

3,  执行继承类的构造函数的正文。

 

关于清理工作,虽不常用,但是个非常需要小心的工作。

 

一个好的构造函数应该,“用最少的工作量把对象的状态设置好,而且要尽可能的避免去调用方法”构造函数唯一能安全调用的方法就是基类的final方法。(这一条也同样适用private,因为它自动就是final)他们不会覆写,因此也不会产生这种意外的行为。

1>     在了解了多态性的一些概念后,我们再来看看类的设计

在类的继承方式里有种方式叫“纯继承”就像下图


由于有着相同的接口,基类可以接受任何发送给派生类的消息。你所要做的,只是将派生类的对象上传,然后就不再需要知道这个对象是什么类型的了。所有的对象都交由多态性来处理。看起来这是一个很好的办法,但事实是很多时候你的派生类都会有比基类更多的接口或者方法比如下面这个图。


看起来这才是实际中常常用到的情形,但同时它也带来了一个缺点,不能通过基类访问派生类的扩展方法,如果在程序中出现了这样的错误,系统会抛出一个
ClassCastException 的异常,这种运行时的类型检查被称为“运行时的类型鉴别run-time type identification (RTTI)” 关于RTTI在后面的学习中还有更详细的介绍。

 

最后有个重要的概念再重申一下:人们常常会将多态性同java的那些非面向对象的特性相混淆,比如方法的重载,它常常会被当作面向对象的特点介绍给大家。千万记住“不是后绑定的,就不是多态性”。(我也以为重载是多态性的一种体现 。汗~)

 

面向对象编程:Java与Python的类、对象和多态性 本文深入探讨了面向对象编程的核心概念,包括类、对象、继承、多态和封装。通过Java和Python的代码示例,展示了如何在两种语言中实现多态和封装,以及数据类型和变量在编程中的重要性。通过理解这些基本概念,开发人员能够创建出更加模块化、可维护和可扩展的代码。 阅读详情

相关推荐

深入理解C#的继承与多态性

本文深入探讨了C#编程语言中的继承和多态性,包括新的可访问性修饰符、覆盖和动态绑定规则、以及如何正确使用继承。同时,文章还涉及了构造函数的规则、运行时类型识别、命名空间、扩展方法、属性等高级特性,并对比了C#与Java在这些方面的不同。最后,文章指出了C#中缺失的面向对象机制,如合同和多重继承,并提到了Spec#这一实验性语言。

weixin_31688273的博客 622

java多态性的奇妙之旅

本文介绍了Java中多态性的概念和实现方法。继承和接口是实现多态性的两种常见方式。通过多态性,我们可以使用统一的接口来处理不同类型的对象,使得代码更具灵活性、可扩展性和可维护性。多态性在实际开发中有许多应用场景,包括多态的参数、多态的集合和多态的方法重写等。通过合理利用多态性,我们可以编写更通用、灵活和可扩展的代码。

alive_new的博客 136

深入探索Java编程的学习之旅

本博客文章以《Head First Java》一书的章节内容为基础,深入探讨了Java编程的核心概念和技巧。文章从Java的语法、面向对象编程,到内存管理、异常处理等多方面,详细解析了学习Java的必要知识。通过两位作者Kathy和Bert的个人经历和观点,本文向读者展示了如何将学习理论应用于实际编程中,并提供了关于如何有效学习Java编程的指导。

weixin_42613018的博客 701

Java之旅(9)多态性

多态性是继数据抽象和继承后,面向对象语言的第三个特征。 绑定(binding)(看起来到像一个音译词):将方法的调用连到方法本身被称为绑定,当绑定发生在程序运行之前,被称做前绑定(earlybinding),而在程序运行的时候根据对象的类型来决定该绑定方法的成为后绑定,也叫运行时绑定(run-time binding)或动态绑定(dynamic binding);java的所有方法都采用后

JAVA之旅 3752

从X86到ARM:将VINS-Fusion-GPU和ego-planner迁移到Jetson Orin-NX时,我踩过的那些‘环境差异’坑

本文详细介绍了将VINS-Fusion-GPU和ego-planner从X86平台迁移到Jetson Orin-NX(ARM架构)时遇到的环境差异问题及解决方案。内容涵盖ARM与X86的架构差异、依赖管理、性能调优和硬件接口适配,特别强调了CUDA在ARM平台上的优化配置和内存访问技巧,帮助开发者高效完成跨平台迁移。

weixin_42647395的博客 120

STM32L476低功耗实战:LPTIM精准定时唤醒STOP2模式与系统级功耗优化

本文深入探讨了STM32L476低功耗实战技巧,重点解析了LPTIM精准定时唤醒STOP2模式的配置与优化。通过详细的步骤指南和实战经验分享,帮助开发者实现系统级功耗优化,特别适合电池供电设备开发。文章涵盖LPTIM1定时器配置、STOP2模式进入流程及常见问题排查,助力将整机功耗降至8.2uA级别。

weixin_33686714的博客 436

java之旅 多态性和instanceof 关键字

多态性:对象在运行过程中的多种形态 包括: 1.方法的重载与重写 2.对象的多态性,例如用父类引用指向小的类型 ,子类可以用父类的方法,即抽象 但要把父类实例强制转换为子类引用时,为了避免类型转换异常,要在转换前做类型检查 用instanceof做判断 ...

be_lxx1的博客 238

微信中调起支付宝支付

微信中调用支付宝支付,首先我们知道微信是不能直接调用支付宝的,所以我们需要使用一个中间页提示用户在浏览器中打开,然后进行网页支付或打开app支付。以下为详细唤起支付宝的步骤、业务代码以及相关页面图。 如有问题欢迎评论留言,看到定回复哦^_^\(^o^)/~ 一、微信中唤起支付宝,有几个步骤: 1、中间页引导用户在浏览器中打开去唤起支付宝。 2、浏览器中打开支付宝或app中打开支付宝。 3...

han_calligrapher的博客 2万+

Java多态性的“飘渺之旅”

原文出处:斯武丶风晴摘要: 如何从Java多态性进行飘渺之旅呢? 我们用例子来旅行。 1 朵星人A:人类,是一个很奇妙的物种。 2 朵星人B:他们好像分为两种,嗯 先生,以及美女? 3 朵星人C:对,更年轻的有叫 美少女的。 4 朵星人D:他们之间怎么打招呼的?我们问问AI(编译器大佬)吧。。 5 朵星人A:可以有。启动吧~第一次启动: 1 /** 2 * 编译时多态 ...

weixin_30407099的博客 119

终于找到两个稳定好用的Docker镜像加速源,拉取速度提升几十倍!

国内使用Docker经常遇到镜像拉取慢、超时失败的问题🐳 本文分享两个亲测好用的免费镜像加速源⚡ 实测拉取速度从十几分钟缩短到几十秒,稳定性接近100%📊 支持一键配置脚本,支持多平台使用✨

XiaoqiangClub的博客 954

【Python机器学习】主成分分析(PCA):高维数据的“瘦身术“

主成分分析(PCA)的历史可以追溯到1901年,当时Karl Pearson首次提出了这个概念。在计算机还不存在的年代,PCA是一个纯粹的数学构想,用来简化多变量数据的分析。几十年后,当计算机出现时,PCA成为了数据分析中最早实现的算法之一。从那时起,超过一个世纪的发展中,PCA一直保持着其核心的理论框架和实用价值,这本身就是对这个方法深刻科学性的证明。在现代深度学习时代,许多人可能会认为PCA已经过时了。但事实恰好相反。

nmdbbzcl的博客 981

Java之旅(10)多态性 (续) & 接口(interface)

 1>     在了解了多态性的一些概念后,我们再来看看类的设计在类的继承方式里有种方式叫“纯继承”就像下图由于有着相同的接口,基类可以接受任何发送给派生类的消息。你所要做的,只是将派生类的对象上传,然后就不再需要知道这个对象是什么类型的了。所有的对象都交由多态性来处理。看起来这是一个很好的办法,但事实是很多时候你的派生类都会有比基类更多的接口或者方法比如下面这个图。看起来

JAVA之旅 4800

CarSim仿真快速入门(十八)-CarSim2021中的混合动力和纯电动系统

CarSim和TruckSim包括用于电动汽车(BEV)和混合电动汽车(HEV)的动力总成系统。电动和混合电动系统可与所有现有驱动系统配合使用,例如:FWD,RWD,AWD和多轴驱动系统。混合动力/电动系统模型还包括电池管理控制。CarSim或TruckSim中的默认动力总成是为闭环速度控制器提供的备用动力总成。要安装和使用完整的动力总成,请从Vehicle: Assembly库或Vehicle: Lead Unit 库链接到Powertrain数据集。在“动力总成”界面上,从下拉列表控件中选择以下三个选项

小明师兄的博客 7456

Java学习之旅:从入门到进阶的系统总结

Spring MVC是Java EE中一个流行的框架,它基于Spring框架,提供了MVC设计模式的实现。Spring MVC通过注解和配置文件简化了Web开发,支持请求映射、数据绑定、视图解析等功能。Java是一门功能强大、应用广泛的编程语言,学习Java不仅可以掌握一门实用的编程技能,还可以深入了解面向对象编程、多线程编程、网络编程等重要概念。通过本文的系统总结,希望你对Java的学习有了更清晰的思路和方向。

吾为热爱计科,致力于知识分享的践行者,此博客是我在这条道路上留下的足迹。 3647

qq对接openclaw,通过qq发送命令

把 OpenClaw 接入 QQ 和微信,目前主流的微信文章和教程主要提供了两种截然不同的路径。我为你梳理了它们的核心区别和关键步骤,你可以根据自己的需求来选择。

suny8的专栏 272

【电力电子】基于STM32F103C8T6单片机双极性SPWM逆变(硬件篇)

输入电压采集上图为本设计的电源电路,图中 D1 为二极管, 其目的是防止正负极电源反接, 由于二极 管的正向导通特性, 用户反接电源时亦不会烧坏后级电路。图中 R8、R9 组成分压电路, 由单片机 AD 采集 IO 口 P14 采集 AD 值, 并由计算公式电压 =133300(AD/4096)mV;

Naiva的博客 1995

【Java探索之旅】多态:重写、动静态绑定

在面向对象编程中,重写和动静态绑定是重要的概念,影响着代码的执行流程和行为。通过重写,子类可以重新实现父类的方法,实现个性化的行为;而动静态绑定则决定了方法调用时的具体行为。本文将深入探讨重写的规则、设计原则以及动静态绑定的概念和条件,帮助您更好地理解和运用这些概念在Java编程中的重要性和实际应用。通过本篇你已经了解了重写和动静态绑定在面向对象编程中的重要性和实现条件。重写可以让子类根据需要重新定义父类的方法,实现个性化的行为;

屿小夏.的知识博客 1279

pscad IEEE标准系统搭建说明

pscad IEEE标准系统搭建说明,包含典型的IEEE 9节点、14节点、30节点、39节点和118节点系统。内含标准测试系统的原始数据和潮流结果。

python之旅:面向对象之多态、多态性

一 多态 多态指的是一类事物有多种形态 eg:动物有多种形态:猫,狗,猪 class Animal: #动物类 def eat(self): #吃 pass def drink(self): #喝 pass def sleep(self): #睡 pass class Cat(Anima...

weixin_30337251的博客 177

数学建模模型总结

这是本人在两年内准备参加数学建模竞赛搜集到的模型资料,已经经过了本人的筛选和整理,希望能够对准备参加数学建模竞赛的学弟学妹们提供一些帮助!

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

【Java探索之旅】抽象类:规范行为、提高重用性

抽象类作为面向对象编程中重要的概念之一,扮演着定义公共接口、规范子类行为、实现代码重用和多态性等角色。通过抽象类,我们可以更好地组织和设计代码结构,提高代码的可维护性和可扩展性。本文将深入探讨抽象类的概念、语法、特性及作用,帮助读者更好地理解和运用抽象类在Java编程中的实际应用和优势。抽象类作为一种抽象和规范的方式,能够帮助我们定义公共接口、规范子类行为、实现代码重用和多态性。使用抽象类可以提高代码的灵活性和可维护性,避免错误的发生,并通过编译器的校验及时发现潜在问题。

屿小夏.的知识博客 799

SIMATIC S7-1200, S7-1500 PID 控制[手册]

SIMATIC S7-1200, S7-1500 PID 控制[手册]

JAVA 泛型意淫之旅(二)

编译器如何处理泛型   泛型类编译后长什么样? 接上文,JAVA 泛型意淫之旅1,成功迎娶白富美后,终于迎来了最振奋人心的一刻:造娃!造男娃还是造女娃?对于我们程序猿来说,谁还在乎是男娃女娃,只要是自己的娃,就是好娃!但不知道父母们是不是这么想的,我们先搞一个造娃类,问一问造出不同的娃,父母的态度是什么。 public class MakeBaby<T> { priv...

qianfeng_dashuju的博客 1234

Java 编程之旅:在困惑与突破中成长

他创建了各种不同的类,尝试赋予它们不同的属性和方法,就像在魔法森林中尝试与不同的精灵家族交流。有时候,他会因为一个小小的语法错误而导致整个程序无法运行,就像在森林中不小心触动了某个机关,引发了一系列意想不到的麻烦。这一发现让小明兴奋不已,他仿佛看到了更多编程世界的奇妙之处,也离自己的梦想更近了一步。但他知道,不能被这些困难阻挡,因为他的目标 —— 创造改变校园生活的软件,就像远方闪耀的灯塔,指引着他继续前进。继承让他明白,不同的精灵家族可以有共同的祖先,它们继承了祖先的某些特性,同时又有自己独特的能力。

2301_82115272的博客 706

编程语言中的魔法从Java到C++的奇妙之旅

这片魔法王国中的“内存”由Java虚拟机(JVM)统一管理,它通过复杂的标记-清除、复制等算法,自动识别并清理那些不再被引用的对象,将程序员从繁琐且易错的内存释放工作中解放出来。Java的泛型主要通过类型擦除实现,在编译后类型信息便被擦除,更多是为了确保编译时的类型安全,运行时并无太多开销。编译器会为每一种用到的具体类型生成一份特化的代码,这虽然可能导致代码膨胀,但能带来零运行时开销的极致性能,是实现标准模板库(STL)中各种高效容器的基石。与Java的自动化守护不同,C++更像是一门要求精准的炼金术。

全球失控 412

开启 Java 学习之旅

Java,作为一门极具影响力的编程语言,在当今的科技领域中占据着举足轻重的地位。对于想要踏入编程世界的新手来说,开启 Java 学习之旅是一个充满挑战与惊喜的过程。

zsnandzmn的博客 1043

java 本学期_本学期JAVA总结

时光飞逝,本学期对于JAVA的学习逐渐步入尾声,所以我将会借助本次博客展开在这一学期对于JAVA(面向对象设计)的总结。在还未开学的时候,我便对JAVA有一些基本的了解,但一直处于懵懵懂懂的状态,因为所拥有的编程思想似乎还停留在c语言(面向过程设计)中,包括开始JDK以及eclipse的调试都让我颇感陌生,感觉与C语言的编程思想似乎截然不同,怀揣着憧憬的心和对JAVA知识的渴望便展开了对JAVA的...

weixin_30536391的博客 126

互联网大厂Java面试:谢飞机的奇幻面试之旅

SpringBoot是Spring的子项目,旨在简化Spring应用的开发,提供开箱即用的功能。JUC是Java提供的并发工具包,包含多线程编程的各种工具类,如Executor、Semaphore、CountDownLatch等,提升了Java的并发处理能力。MyBatis是一个持久层框架,与JDBC相比,简化了数据库层的操作,它支持自定义SQL、存储过程以及高级映射。:哈哈,Docker是一种开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中。:呃,多态性啊,就是……

weixin_43935051的博客 251
上一篇: java之旅 (四)隐藏实现 & 复用类
下一篇: java之旅 (六)接口
C_plus_learner
博客等级 码龄22年 0粉丝 9原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值