初步接触多态

2024-03-27 11:50
文章标签 初步 多态 接触

本文主要是介绍初步接触多态,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

(1)多态概述

所谓多态就是指程序中定义的引用变量所指向的具体类型和通过该引用变量发出的方法调用在编程时并不确定,而是在程序运行期间才确定,即一个引用变量倒底会指向哪个类的实例对象,该引用变量发出的方法调用到底是哪个类中实现的方法,必须在由程序运行期间才能决定。因为在程序运行时才确定具体的类,这样,不用修改源程序代码,就可以让引用变量绑定到各种不同的类实现上,从而导致该引用调用的具体方法随之改变,即不修改程序代码就可以改变程序运行时所绑定的具体代码,让程序可以选择多个运行状态,这就是多态性。

(2)多态详述

       比如你是一个酒神,对酒情有独钟。某日回家发现桌上有几个杯子里面都装了白酒,从外面看我们是不可能知道这是些什么酒,只有喝了之后才能够猜出来是何种酒。你一喝,这是剑南春、再喝这是五粮液、再喝这是酒鬼酒….在这里我们可以描述成如下:

      酒 a = 剑南春

      酒 b = 五粮液

      酒 c = 酒鬼酒

      …

      这里所表现的的就是多态。剑南春、五粮液、酒鬼酒都是酒的子类,我们只是通过酒这一个父类就能够引用不同的子类,这就是多态——我们只有在运行的时候才会知道引用变量所指向的具体实例对象。多态在这个例子中也可以解释为,酒在不同的引用中所表现出来的不同形态或者状态。酒既可以是五粮液,也可以是酒鬼酒。酒既有了某种形态的特性,也保留了所属于“酒”这一个大类的基本属性。

      诚然,要理解多态我们就必须要明白什么是“向上转型”。在继承中我们简单介绍了向上转型,这里就在啰嗦下:在上面的喝酒例子中,酒(Win)是父类,剑南春(JNC)、五粮液(WLY)、酒鬼酒(JGJ)是子类。我们定义如下代码:

      JNC a = new  JNC();

      对于这个代码我们非常容易理解无非就是实例化了一个剑南春的对象嘛!但是这样呢?

      Wine a = new JNC();//父类类型指向子类实例对象

      在这里我们这样理解,这里定义了一个Wine 类型的a,它指向JNC对象实例。由于JNC是继承与Wine,所以JNC可以自动向上转型为Wine,所以a是可以指向JNC实例对象的。这样做存在一个非常大的好处,在继承中我们知道子类是父类的扩展,它可以提供比父类更加强大的功能,如果我们定义了一个指向子类的父类引用类型,那么它除了能够引用父类的共性外,还可以使用子类强大的功能。

      但是向上转型存在一些缺憾,那就是它必定会导致一些方法和属性的丢失,而导致我们不能够获取它们。所以父类类型的引用可以调用父类中定义的所有属性和方法(这些可能在子类中被重新定义过,父类中此时的调用会被覆盖),对于只存在与子类中的方法和属性它就望尘莫及了。

这一点,我们可以通过一小段代码来体会一下。

 

 仔细观察两段代码。在第一段代码中,我们定义了一个Animal类,一个Cat类。我们在Animal类中定义了 函数eat(),在Cat类中对eat()方法进行的重写,并添加了一个在父类中没有定义过的函数nun()。在主函数中分别对与子类实例对象,和指向子类实例对象的父类类型进行两种函数的调用测试。子类对象可以完美的运行在子类中进行重新编写或者初步定义的函数,但指向子类实例对象的父类类型在调用num()函数时出现了错误,这是因为nun()函数在Animal类中没有被定义过。

由此我们可以得到多态应用的前提

  • 要有继承或实现关系
  • 要有方法的重写
  • 要有父类引用指向子类对象

(3)扩展-使用场景

根据多态不能调用子类单独有的代码的特性,当所要创建的对象在一种基本情况上面要表现不同的特性时,我们可以使用多态来让对象表现不同的状态。具体情况包括

  1. 定义方法参数列表时
  2. 定义方法返回值类型时
  3. 定义类的成员变量时
  4. 定义数组元素类型时
  5. 都定义为父类类型,这样就可以传递、返回、赋值、装任意子类类型的对象定义时,定义父类类型使用时使用子类类型的对象,等等。

在这些情况下,若不使用多态来解决问题,将会导致代码出现以下几种问题:

  • 1:代码复用性差:有几种灯泡类型 在台灯类中就需要定义几个属性 而且在on方法中进行多次if判断
  • 2:扩展性差:有新灯泡类型 需要更改Lamp类 添加新属性 修改on方法
  • 3:耦合性强

例如:

public class LianXi1_1 {
//不使用多态public static void main(String[] args) {//创建灯泡对象RedBulb1 r1=new RedBulb1();GreenBulb1 g1=new GreenBulb1();//创建台灯对象Lamp1 l1=new Lamp1();//给台灯对象的属性赋值l1.r=r1;l1.g=g1;//调用台灯对象的方法l1.on();}
}
class Lamp1{//台灯类//灯泡是台灯的一个数据RedBulb1 r;//定义成员变量记录需要安装的红灯泡GreenBulb1 g;//定义成员变量记录需要安装的绿灯泡void on() {if (r!=null) {r.light();}if (g!=null) {g.light();}}
}
class RedBulb1{void light(){System.out.println("红灯泡  发光:红");}
}
class GreenBulb1{void light(){System.out.println("绿灯泡  发光:绿");}
}
public class LianXi1_2 {
//使用多态public static void main(String[] args) {//创建灯泡对象RedBulb r1=new RedBulb();GreenBulb g1=new GreenBulb();//创建台灯对象Lamp l1=new Lamp();//给台灯对象的属性赋值l1.b=r1;l1.b=g1;//调用台灯对象的方法l1.on();}class Lamp{//台灯类//灯泡是台灯的一个数据//定义父类类型的成员变量Buib2 b;void on() {if (b!=null) {b.light();}}
}
//抽取子类中共同数据和功能形成父类
abstract class Buib2{abstract void light();
}
//让所有子类继承父类
class RedBulb extends Buib2{//根据子类需求  实现父类方法void light() {System.out.println("红灯泡  发光:红");}
}
class GreenBulb extends Buib2{void light() {System.out.println("绿灯泡  发光:绿");}
}

两相对比下可以看出,在这种情况下使用多态不仅可以让代码有序,还可以有更强的逻辑性。
 

(4)小结

1.多态的使用前提:

  • 要有继承或实现关系
  • 要有方法的重写
  • 要有父类引用指向子类对象

2.多态的好处和弊端

(1)好处

  • 提高程序的扩展性。定义方法的时候,使用父类型作为参数,在使用的时候,使用具体的子类型参与操作

(2)坏处

  • 不能访问子类中的特有成员

3.多态中的转型

  • 向上转型
    父类引用指向子类对象就是向上转型
  • 向下转型
    格式:子类型 对象名 = (子类型)父类引用;

这篇关于初步接触多态的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/852017

相关文章

C++对象布局及多态实现探索之内存布局(整理的很多链接)

本文通过观察对象的内存布局,跟踪函数调用的汇编代码。分析了C++对象内存的布局情况,虚函数的执行方式,以及虚继承,等等 文章链接:http://dev.yesky.com/254/2191254.shtml      论C/C++函数间动态内存的传递 (2005-07-30)   当你涉及到C/C++的核心编程的时候,你会无止境地与内存管理打交道。 文章链接:http://dev.yesky

JavaWeb 学习笔记 spring+jdbc整合开发初步

JdbcTemplate类是Spring的核心类之一,可以在org.springframework.jdbc.core中找到它。JdbcTemplate类在内部已经处理数据库的建立和释放,可以避免一些常见的错误。JdbcTemplate类可直接通过数据源的应用实例化,然后在服务中使用,也可在xml配置中作为JavaBean应用给服务使用直接上一个实例步骤1.xml配置 <?xml version

多态的分类

多态分为两种:通用的多态和特定的多态。两者的区别是前者对工作的类型不加限制,允许对不同类型的值执行相同的代码;后者只对有限数量的类型有效,而且对不同类型的值可能要执行不同的代码。 1,通用的多态又分为参数多态(parametric)和包含多态(inclusion); (1)参数多态:采用参数化模板,通过给出不同的类型参数,使得一个结构有多种类型。 例如:泛型   (2)包含多

第一次接触Swing

学习java版的HslCommunication发现使用的是Swing,所以了解了一下~ 了解: Swing是Java的标准库(Java Foundation Classes, JFC)的一部分,用于构建桌面应用程序的图形用户界面(GUI)。它是Java AWT(Abstract Window Toolkit)的增强版,提供了更多的组件、更好的外观和感觉,以及更丰富的功能。Swing使用

【从0实现React18】 (三) 初探reconciler 带你初步探寻React的核心逻辑

Reconciler 使React核心逻辑所在的模块,中文名叫协调器,协调(reconciler)就是diff算法的意思 reconciler有什么用? 在前端框架出现之前,通常会使用 jQuery 这样的库来开发页面。jQuery 是一个过程驱动的库,开发者需要直接调用浏览器的宿主环境 API,例如 DOM 操作等。这意味着开发者需要手动管理页面状态和交互,通过执行一系列的操作来更新页面。

Java参数传递造成参数值改变的情况--值传递和引用传递的初步理解

值传递 值传递,像int,float之类的简单类型进行的是值传递 [java]  view plain copy print ? public static void main(String[] args) {       int i = 900;       System.out.println(i);          changeInt(i);       S

redis初步认识(一)

文章目录 概述安装编译 string数据结构基础命令应用对象存储累加器 list结构基础命令应用栈(先进后出FILO)队列 HASH基础命令存储结构应用存储对象 小结 概述 redis 是一个远程字典服务;当然,redis是内存数据库,kv数据库,最基础的数据结构有(string, list, hash, set, zset)几种。 安装编译 在ubuntu云服务器上安

C++面向对象三大特性--多态

C++面向对象三大特性–多态 文章目录 C++面向对象三大特性--多态1.虚函数(Virtual Function)2.纯虚函数(Pure Virtual Function)和抽象类(Abstract Class)3.重写(Override)4.动态绑定(Dynamic Binding)或迟绑定(Late Binding)5.虚析构函数和纯虚析构5.1虚析构函数5.2纯虚析构函数5.3总结

初步组装的杂合基因组如何去冗余

redundans的目标是辅助杂合基因组的组装,输入文件可以是组装的contig,测序文库以及额外的参考基因组,最后用于搭建出scaffold级别的纯合基因组组装结果。包括如下几个步骤: 从头组装: 它会调用Platanus、SSPACE3进行组装去冗余: 从最初组装中去除冗余的序列scaffolding: 利用双端测序将contig进行搭接gap closing: 即填补scaffold中的N

Linux|操作系统运维|磁盘性能检测之fio和iostat的初步使用

前言: 有的时候,我们接手一个新的服务器的时候,需要了解该服务器的磁盘性能是否可靠,比如,磁盘是否有坏道,磁盘的读写性能是否能够符合我们将要部署的服务,例如数据库服务,如果该数据库是一个读写比较频繁也就是IO比较高的数据库,那么,该磁盘是否能够支持高IO呢? 针对以上需求,建议使用工具fio和iostat这两个工具 一、 iostat在centos7下的安装 配置update源即可 i