课时75:对象向上转型
摘要:对象转型的处理属于多态性,而这一特性必须在继承行的基础上实现。
1. 常规覆写操作
2. 向上转型覆写操作
3. 向上转型的实际作用
4. 为什么不使用重载来解决参数的统一性问题
01. 常规覆写操作
范例:观察一个简单代码
首先 Message和DateBaseMseeage有继承关系。然后接着写后续代码,如下图所示,那此代 码执行的是哪一个?
代码如下:
class Message { public void print() { System.out.println("www.mldn.cn"); } } class DataBaseMessage extends Message { public void print() { System.out.println("Oracle数据库连接信息...." ); } } public class JavaDemo { public static void main(String args[]) { DataBaseMessage msg = new DataBaseMessage(); msg.print(); } }
应该执行的是Oracle的连接。
本程序是一个最简单的方法覆写操作实现,整体的程序之中可以发现,由于现在实例化的是子类对象,并且子类对象覆写了父类中的Print()方法,所以调用的是被覆写过的方法。
02. 向上转型覆写操作
范例:观察向上转型
代码如下:
class Message { // Message类的其他代码未显示在图中 } class DataBaseMessage extends Message { public void print() { System.out.println("Oracle数据库连接信息...." ); } } public class JavaDemo { public static void main(String args[]) { DataBaseMessage msg = new DataBaseMessage(); msg.print(); } }
整个代码中,DateBaseMessage 是Message的一个子类,向上转型。
代码如下:
class Message { // Message类的其他代码未在图中显示 } class DataBaseMessage extends Message { public void print() { System.out.println("Oracle数据库连接信息...." ); } } public class JavaDemo { public static void main(String args[]) { Message msg = new DataBaseMessage(); // 向上转型 msg.print(); } }
向上转型的过程很简单,没有任何强制。此时的代码不要看类名称 Message,关键字看 New的谁,并且方法 Print有没有被覆写。那此时关键字 New的是DateBaseMessage,并且方法成功实现了覆写,这个时候的输出结果应该为 Oracle的连接:
在整个代码的编写过程中,千万别看前面的 “Message msg”,
只是一种类型。那么这个时候就要进行思考了,向上转型的处理有什么实际的用处呢?
03. 向上转型处理的实际作用
例如以下程序:
class Message { public void print() { System.out.println("www.mldn.cn"); } } class DataBaseMessage extends Message { public void print() { System.out.println("Oracle数据库连接信息...." ); } } class WebServerMessage extends Message { public void print() { System.out.println("WEB服务器连接信息...." ); } } public class JavaDemo { public static void main(String args[]) { fun(new DataBaseMessage()); // Message msg = new DataBaseMessage(); fun(new WebServerMessage()); // Message msg = new WebServerMessage(); } public static void fun(Message msg) { // 不管现在传递是哪一个子类对象,都可以用一个参数来接收 msg.print(); } }
代码中有两个子类,分别为 DateBaseMessage与 WebServerMessage,所有的子类都可以向上父类自动转型。代码之中的 fun(new DateBaseMessage())
就相当于Message msg = new DateBaseMessage()
这个操作;同样的,fun(new WebServerMessage())
就相当于Message msg = new WebServerMessage()
这个操作。不管现在传递的是哪一个子类都可以用一个参数来接收。但是大家记住,每个子类都有自己不同的 Print方法。
运行结果为:
运行结果可知,传入 DateBaseMessage的时候,输出的是 “Oracle数据库连接信息……”;传入的 WebServerMessage的时候,输出的是“WEB服务器连接信息……”。
所以,向上转型的主要特点在于可以对参数进行统一的设计。但是为什么此时不使用重载来解决当前问题呢?
04. 为什么不使用重载来解决参数的统一性问题
现在的操作利用了重载解决了当前的设计,的确可以实现与之前完全一样的效果。但是在进行程序类设计的时候除了满足于当前的要求之外,还需要做出可维护性的设计,若现在随着项目的发展,Message产生了3W个子类,那么这个时候每当扩充一个Message子类之后就需要追加一个 Fun()对的方法重载,这样就对程序的维护性造成很大的影响。
用这个多态性的向上转型,主要的目的就是为了解决参数的统一问题。所以对象转型之中的向上转型,明确实现的是参数接收或返回参数的统一性,这一点是向上转型的目标。对于向上转型,主要看的是实例化的是哪一个子类,并且子类有没有进行方法覆写,如果覆写了,那么调用的方法就是被覆写的方法。
向上转型是开发中主要使用的技术。