java对象间的转型,详细讲述Java中的对象转型

向上转型:子类对象转为父类,父类可以是接口。公式:Father f = new Son();Father是父类或接口,son是子类。

向下转型:父类对象转为子类。公式:Son s = (Son)f;

503680162005ca1c29a9e572663e2c29.png

我们将形参设为父类Animal类型,当执行test.f(c)时,内存情况如下图:

b676f4a6d886b40c2df690058812b22b.png

c作为Cat类型传入,Animal a作为形参,相当于执行了Animal a = new Cat(),这时a和c同时指向Cat对象,但此时a不能访问Cat类扩展的数据成员,所以再将a强转成Cat类型即可。如果不存在这样的转型机制,则针对猫和狗我们还要分别写两个函数f(Cat c)和f(Dog d)。但其实上图程序的可扩展性也不是最好的。我们还可以利用动态绑定(即多态)将扩展性进一步提升。多态机制的三个前提分别是:

(1)要有继承

(2)要重写,即子类对父类中某些方法进行重新定义

(3)要向上转型,用父类引用指向子类对象。

下面来看一个例子:

class Animal { private String name; /**

* 在Animal类自定义的构造方法

* @param name */

Animal(String name) { this.name = name;

} /**

* 在Animal类里面自定义一个方法enjoy */

public void enjoy() {

System.out.println("动物的叫声……");

}

}class Cat extends Animal { private String eyesColor; /**

* 在子类Cat里面定义Cat类的构造方法

* @param n

* @param c */

Cat(String n, String c) { /**

* 在构造方法的实现里面首先使用super调用父类Animal的构造方法Animal(String name)。

* 把子类对象里面的父类对象先造出来。 */

super(n);

eyesColor = c;

} /**

* 子类Cat对从父类Animal继承下来的enjoy方法不满意,在这里重写了enjoy方法。 */

public void enjoy() {

System.out.println("我养的猫高兴地叫了一声……");

}

}/**

* 子类Dog从父类Animal继承下来,Dog类拥有了Animal类所有的属性和方法。

* @author gacl

* */class Dog extends Animal { /**

* 在子类Dog里面定义自己的私有成员变量 */

private String furColor; /**

* 在子类Dog里面定义Dog类的构造方法

* @param n

* @param c */

Dog(String n, String c) { /**

* 在构造方法的实现里面首先使用super调用父类Animal的构造方法Animal(String name)。

* 把子类对象里面的父类对象先造出来。 */

super(n);

furColor = c;

} /**

* 子类Dog对从父类Animal继承下来的enjoy方法不满意,在这里重写了enjoy方法。 */

public void enjoy() {

System.out.println("我养的狗高兴地叫了一声……");

}

}/**

* 子类Bird从父类Animal继承下来,Bird类拥有Animal类所有的属性和方法

* @author gacl

* */class Bird extends Animal { /**

* 在子类Bird里面定义Bird类的构造方法 */

Bird() { /**

* 在构造方法的实现里面首先使用super调用父类Animal的构造方法Animal(String name)。

* 把子类对象里面的父类对象先造出来。 */

super("bird");

} /**

* 子类Bird对从父类Animal继承下来的enjoy方法不满意,在这里重写了enjoy方法。 */

public void enjoy() {

System.out.println("我养的鸟高兴地叫了一声……");

}

}/**

* 定义一个类Lady(女士)

* @author gacl

* */class Lady { /**

* 定义Lady类的私有成员变量name和pet */

private String name; private Animal pet; /**

* 在Lady类里面定义自己的构造方法Lady(),

* 这个构造方法有两个参数,分别为String类型的name和Animal类型的pet,

* 这里的第二个参数设置成Animal类型可以给我们的程序带来最大的灵活性,

* 因为作为养宠物来说,可以养猫,养狗,养鸟,只要是你喜欢的都可以养,

* 因此把它设置为父类对象的引用最为灵活。

* 因为这个Animal类型的参数是父类对象的引用类型,因此当我们传参数的时候,

* 可以把这个父类的子类对象传过去,即传Dog、Cat和Bird等都可以。

* @param name

* @param pet */

Lady(String name, Animal pet) { this.name = name; this.pet = pet;

} /**

* 在Lady类里面自定义一个方法myPetEnjoy()

* 方法体内是让Lady对象养的宠物自己调用自己的enjoy()方法发出自己的叫声。 */

public void myPetEnjoy() {

pet.enjoy();

}

}public class Jerque { public static void main(String args[]) { /**

* 在堆内存里面new了一只蓝猫对象出来,这个蓝猫对象里面包含有一个父类对象Animal。 */

Cat c = new Cat("Catname", "blue"); /**

* 在堆内存里面new了一只黑狗对象出来,这个黑狗对象里面包含有一个父类对象Animal。 */

Dog d = new Dog("Dogname", "black"); /**

* 在堆内存里面new了一只小鸟对象出来,这个小鸟对象里面包含有一个父类对象Animal。 */

Bird b = new Bird(); /**

* 在堆内存里面new出来3个小姑娘,名字分别是l1,l2,l3。

* l1养了一只宠物是c(Cat),l2养了一只宠物是d(Dog),l3养了一只宠物是b(Bird)。

* 注意:调用Lady类的构造方法时,传递过来的c,d,b是当成Animal来传递的,

* 因此使用c,d,b这三个引用对象只能访问父类Animal里面的enjoy()方法。 */

Lady l1 = new Lady("l1", c);

Lady l2 = new Lady("l2", d);

Lady l3 = new Lady("l3", b); /**

* 这三个小姑娘都调用myPetEnjoy()方法使自己养的宠物高兴地叫起来。 */

l1.myPetEnjoy();

l2.myPetEnjoy();

l3.myPetEnjoy();

}

}

上面的例子中,我们发现,如果我们想要加入新的动物,只需定义相应的类继承Animal,完全不用动任何一处代码,因为这里运用了面向对象最核心的东西——多态。与之前的例子不同,虽然我们一直强调当用父类的引用指向子类对象,父类无法访问子类自己的成员,但是方法与数据成员不同,具体调哪一个方法是等到运行时决定的,new出了什么对象就调用相应对象的方法,取决于实际new出的对象而不是指向对象的引用,所以当传入不同动物类型,mypetEnjoy()就会去执行不同的方法

71cf6cb86e9ccde16349e08c04342d95.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/436149.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++设计模式之一 工厂模式(简单工厂、工厂和抽象工厂)

今天开始这个系列之前,心里有些恐慌,毕竟园子里的高手关于设计模式的经典文章很多很多,特别是大侠李会军、吕震宇 老师的文章更是堪称经典。他们的文笔如行云流水,例子活泼生动,讲解深入浅出。好在他们都是用C#描述&am…

【转】Windows消息传递机制详解

林炳文Evankaka原创作品。转载请注明出处http://blog.csdn.net/evankaka Windows是一个消息(Message)驱动系统。Windows的消息提供了应用程序之间、应用程序与Windows系统之间进行通信的手段。应用程序想要实现的功能由消息来触发,并且靠对消…

设计模式C++实现(2)——单例模式

软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性:封装、继承、多态,真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积累。最近看设计模式的书&#xff0…

设计模式C++实现(3)——建造者模式

软件领域中的设计模式为开发人员提供了一种使用专家设计经验的有效途径。设计模式中运用了面向对象编程语言的重要特性:封装、继承、多态,真正领悟设计模式的精髓是可能一个漫长的过程,需要大量实践经验的积累。最近看设计模式的书&#xff0…

宽字符串忽略大小写比较的实现(原)

宽字符串忽略大小写比较的实现(原) 孙文涛 2008-07-24 在Mac机器平台上没有wcsicmp 或 wcscasecmp之类的函数实现对宽字符忽略大小写的比较,所以实现了好几种方法。 一个自然的思路是: (1) wcscpy 原字符串到tmp字符串; (2) tolower tmp字符串; (3) 然后调用仅存的w…

有关JAVA考试中数据库的题,javaee期末考试题库,用javaEE编写一个题库系统,要怎么做...

javaEE数据库简单问题。你插入2113数据库的时候是把5261它封装为一4102个对象插入的吗?1653如果封装为一个User对象版的权话(User对象有ID和LEVEL两个属性)ResultSet rs ps.executeQuery();User user new User();if(rs.hasNext()){user rs.next();}关于javaee 中j…

oracle 12c sql图形化,Oracle 12c PL/SQL程序设计终极指南

Oracle 12c PL/SQL程序设计终极指南作者:孙风栋;王澜;郭晓惠出版日期:2015年06月文件大小:11.73M支持设备:¥60.00在线试读适用客户端:言商书局iPad/iPhone客户端:下载 Android客户端&#xff1a…

oracle 存储同步,Oracle数据库知识——存储过程篇

在线QQ客服:1922638专业的SQL Server、MySQL数据库同步软件存储过程是一组用于完成特定功能的SQL语句,该语句已编译并存储在数据库中。用户通过指定存储过程的名称并提供参数(如果存储过程具有参数)来执行它。存储过程是数据库中的重要对象。任何设计良好…

使用MvcContrib的FormHelper

MvcContrib的FormHelper提供了三大Helper Html辅助 验证HelperGrid表格Helper下载 下载后将MvcContrib.dll与MvcContrib.Samples.FormHelper.dll引用到Asp.net MVC工程 在Web.Config pages.namespaces加入以下节点 <add namespace"MvcContrib.UI.Tags"/><ad…

WinCE控制面板添加应用程序

WinCE系统中的控制面板和Windows系统中的控制面板原理是一样的&#xff0c;里面就是包含了一些应用程序。WinCE系统的控制面板由Ctlpnl.exe&#xff0c;Control.exe和一些.cpl文件组成&#xff0c;其中Ctlpnl.exe和Control.exe用于控制控制面板的文件夹显示和架构&#xff0c;而…

oracle 游标 904,如何解决Oracle数据库游标连接超出问题

如何解决Oracle数据库游标连接超出问题发布时间&#xff1a;2020-07-21 10:57:35来源&#xff1a;亿速云阅读&#xff1a;103作者&#xff1a;小猪这篇文章主要讲解了如何解决Oracle数据库游标连接超出问题&#xff0c;内容清晰明了&#xff0c;对此有兴趣的小伙伴可以学习一下…

用多媒体库 Bass.dll 播放 mp3 [15] - 设置与获取播放速度

本例效果图:代码文件:unit Unit1;interfaceusesWindows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,Dialogs, StdCtrls, ComCtrls;typeTForm1 class(TForm)OpenDialog1: TOpenDialog;Button1: TButton;Button2: TButton;Button3: TButton;TrackBar1:…

【转】Dicom文件解析!!!!!!

转自&#xff1a;https://blog.csdn.net/leaf6094189/article/details/8510325 Dicom全称是医学数字图像与通讯&#xff0c;这里讲的暂不涉及通讯那方面的问题 只讲*.dcm 也就是diocm格式文件的读取&#xff0c;读取本身是没啥难度的 无非就是字节码数据流处理。只不过确实比较…

VS2008 JS脚本调试总是调试旧代码 真不知道怎么回事?谁能帮帮我呀!

如图,[dynamic]标记的是调试的元文件 xml1.htm[dynamic]和xml.js[dynamic] 我更改后的文件是xml1.htm和xml.js,见图1 2 调试的文件有debugger 更改后的文件我把debugger注了 js脚本中我把变量给改了见3 4 ,所以在浏览新的xml1.htm时,竟然报对象找不到,真实受不了了!!! 为什么我…

【转】C#开发PACS医学影像处理系统(一):开发背景和功能预览

转自&#xff1a;https://www.cnblogs.com/Uncle-Joker/p/13646949.html 本系列文章将从以下模块和大家分享和讨论使用C#开发医学软件PACS和RIS系统&#xff0c; 国内相关资料比较少&#xff0c;也借此机会丰富一下医学软件开发生态&#xff0c;讨论技术难点&#xff0c;希望…

《WF编程》系列之30 - 基本活动:错误处理

《WF编程》系列之30 - 基本活动:错误处理 4.3 错误处理 Fault,故障,现在官方已经将其翻译为错误,那么以后的随笔中我也就采用官方的翻译吧. 错误处理也属于流程控制的一部分,这一节我来介绍一下有关错误处理的活动.错误是指在工作流执行期间发生的异常.我们可以使用错误处理程…

oracle错误27101,ORA-27101ORA-01034错误解决

Oracle已经启动&#xff0c;连接sqlplus后&#xff0c;进行查询&#xff0c;出现下面错误ORA-01034: ORACLE not availableORA-27101: shared memory realm doesOracle已经启动&#xff0c;连接sqlplus后&#xff0c;进行查询&#xff0c;出现下面错误ORA-01034: ORACLE not av…

NOD32升级ID获取器For流星无语更新了

NOD32升级ID获取器For流星无语更新了一下,现在可以直接把用户名密码写入注册表了,连复制/粘贴操作都可以免了...转载于:https://www.cnblogs.com/lxwy/archive/2008/09/05/4420722.html

【转】【C#】使用fo-dicom完成BMP,JPG,PNG图片转换为DICOM文件

转自&#xff1a;https://developer.aliyun.com/article/672065 最近研究了一下DICOM和BMP文件转换的问题&#xff0c;也是很头大。度娘了很久&#xff0c;也在CSDN等论坛看到一些断断续续的文件&#xff0c;最主要的是代码只是片断&#xff0c;不是完整的实现。头大了。 首先…

C++设计模式之二 AbstractFactory模式

设计模式的目的就是尽量减少“变化”对程序的影响&#xff0c;尤其是对客户程序的影响。AbstractFactory模式作为创建型模式的一种&#xff0c;解决的就是“new”在变化中可能引起的问题。 先来看看new有何种不好&#xff0c;举个创建汽车的车门的例子&#xff1a; 很自然的一…