- ubuntu12.04环境下使用kvm ioctl接口实现最简单的虚拟机
- Ubuntu 通过无线网络安装Ubuntu Server启动系统后连接无线网络的方法
- 在Ubuntu上搭建网桥的方法
- ubuntu 虚拟机上网方式及相关配置详解
CFSDN坚持开源创造价值,我们致力于搭建一个资源共享平台,让每一个IT人在这里找到属于你的精彩世界.
这篇CFSDN的博客文章详细讲述Java中的对象转型由作者收集整理,如果你对这篇文章有兴趣,记得点赞哟.
向上转型:子类对象转为父类,父类可以是接口。公式:father f = new son();father是父类或接口,son是子类.
向下转型:父类对象转为子类。公式:son s = (son)f,
我们将形参设为父类animal类型,当执行test.f(c)时,内存情况如下图:
c作为cat类型传入,animal a作为形参,相当于执行了animal a = new cat(),这时a和c同时指向cat对象,但此时a不能访问cat类扩展的数据成员,所以再将a强转成cat类型即可。如果不存在这样的转型机制,则针对猫和狗我们还要分别写两个函数f(cat c)和f(dog d)。但其实上图程序的可扩展性也不是最好的。我们还可以利用动态绑定(即多态)将扩展性进一步提升。多态机制的三个前提分别是:
(1)要有继承 。
(2)要重写,即子类对父类中某些方法进行重新定义 。
(3)要向上转型,用父类引用指向子类对象.
下面来看一个例子:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
|
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()就会去执行不同的方法 。
最后此篇关于详细讲述Java中的对象转型的文章就讲到这里了,如果你想了解更多关于详细讲述Java中的对象转型的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。
目录 进程 其他相关概念 创建线程的两种方式 为什么使用start()方法而不直接使用run()方法 start()方法底层
CURL状态码列表 状态码 状态原因 解释 0 正常访问
ODBC连接类函数 odbc_connect函数:打开一个ODBC连接 odbc_close函数:关闭一个已经打开的ODBC连接 odbc_close_all函数:关闭所有已经打开的ODBC连
作为标题,如何计算从纪元1900到现在使用boost的持续时间? 编辑:很抱歉以前的问题太短。我将再次描述我的问题。 我有关于将生日另存为整数的问题。我创建了四个函数,用法如下: ptime转换为整数
前言 在Java中,有一个常被忽略 但 非常重要的关键字Synchronized今天,我将详细讲解 Java关键字Synchronized的所有知识,希望你们会喜欢 目录 1. 定义 J
详细 JVM 垃圾收集日志的时间戳是收集的开始还是结束? 2016-08-09T21:04:19.756-0400: 224890.317: [GC Desired survivor size 167
我在“Master-Detail”概念上苦苦挣扎,除了一点点(但很重要)的细微差别外,几乎所有东西都按预期工作。我应该在 Storyboard上更改什么以在详细信息 View (屏幕截图底部的右上角)
我希望能够显示表格的详细 View ,但不推送新屏幕,而只显示表格所在的详细 View 。 设置它的最佳方式是什么......如果真的可行的话? ---------------------------
我在我的博客中为我的帖子使用了详细 View ,每篇帖子都有评论,所以我想对它们进行分页,但我不知道该怎么做,因为我请求了帖子模型。我知道如何在功能 View 中执行此操作,但不知道如何在详细 Vie
在下面的代码中,与 pm 对齐,该行是否会 move 整个内存并将其分配给 pm,或者它只会 move p 指向的内存而不是整个数组? int main() { int*
1·下载 https://dev.mysql.com/downloads/mysql/ 2·安装服务 1)管理员运行cmd 2)D: 3)cd D:\mysql
今天以前一直用的SQL Server 2005做开发,偶尔也用MySQL,现入手公司项目,用到SQL Server 2008,于是乎必须安装它,免得出现其他很纠结的小问题,现将自己安装图解分享如下:
1. crontab命令选项 复制代码 代码如下: #crontab -u <-l, -r, -e> -u指定一个用
我们有一个 WPF 应用程序,它有一个主窗口/详细信息窗口,两者都是 WPF 数据网格。当您在上部数据网格中选择一行时,详细信息将显示在下部数据网格中。我想知道从 UI 的角度来看是否有任何关于如何处
在可视化 Perforce 客户端 (p4v) 中有一个选项: 显示文件操作的 p4 命令输出 启用后,在日志 Pane 中,我可以看到这样的详细日志记录: p4 sync /Users/az/ftp
在其他服务器上设置测试环境后,在几个API调用中出现错误。 99%肯定这是MySQL的事情,但是返回的错误根本没有帮助: global name 'sys' is not defined" 我已经导入
我正在维护一个通用的 iOS 应用程序,其开发已开始于 iOS 6。我正在为 iOS 7 更新 UI。现在我遇到了应用程序的 iPad 部分的奇怪问题。这部分遵循使用 UISplitViewContr
我希望我能正确描述这种情况。当它发生时很容易在屏幕上看到,但很难用语言解释,但我会尽力而为。 我有一个带有固定主视图 (UITableView) 和两个详细 View 之一的 UISplitViewC
我尝试在 eclipse 和 intelliJ 参数中使用垃圾收集记录器来配置简单的测试程序。尝试了不同类型的配置,但尚未创建日志文件。 -XX:+PrintGCDetails -XX:+PrintG
正如您所知,.cap 文件中的 java 小程序的输出文件格式必须通过智能卡读卡器/写卡器(如 ACR122 或任何其他读卡器)部署到 java 卡,而且我相信 java 卡与 java 卡之间的部署
我是一名优秀的程序员,十分优秀!