登录  /  注册
首页 > Java > java教程 > 正文

Java向上转型和向下转型的使用介绍(附代码)

不言
发布: 2019-03-19 09:35:07
转载
3291人浏览过

本篇文章给大家带来的内容是关于java向上转型和向下转型的使用介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。

1 向上转型(子类转型成父类)
 举例:

package a.b;

public class A {

public void a1() {

       System.out.println("Superclass");

}

}

A的子类B:

package a.b;

public class B extends A {

public void a1() {

       System.out.println("Childrenclass"); //覆盖父类方法

}

       public void b1(){} //B类定义了自己的新方法

}

C类:

package a.b;

public class C {

public static void main(String[] args) {

       A a = new B(); //向上转型

       a.a1();

}

}
登录后复制

如果运行C,输出的是Superclass 还是Childrenclass?不是你原来预期的Superclass,而是Childrenclass。这是因为a实际上指向的是一个子类对象。当然,你不用担心,Java虚拟机会自动准确地识别出究竟该调用哪个具体的方法。不过,由于向上转型,a对象会遗失和父类不同的方法,例如b1()。有人可能会提出疑问:这不是多此一举吗?我们完全可以这样写:

B a = new B();

a.a1();

确实如此!但这样就丧失了面向抽象的编程特色,降低了可扩展性。其实,不仅仅如此,向上转型还可以减轻编程工作量。来看下面的显示器类Monitor:

package a.b;

public class Monitor{

public void displayText() {}

public void displayGraphics() {}

}

液晶显示器类LCDMonitor是Monitor的子类:

package a.b;

public class LCDMonitor extends Monitor {

public void displayText() {

       System.out.println("LCD display text");

}

public void displayGraphics() {

       System.out.println("LCD display graphics");

}

}

阴极射线管显示器类CRTMonitor自然也是Monitor的子类:

package a.b;

public class CRTMonitor extends Monitor {

public void displayText() {

       System.out.println("CRT display text");

}

public void displayGraphics() {

       System.out.println("CRT display graphics");

}

}

等离子显示器PlasmaMonitor也是Monitor的子类:

package a.b;

public class PlasmaMonitor extends Monitor {

public void displayText() {

       System.out.println("Plasma display text");

}

public void displayGraphics() {

       System.out.println("Plasma display graphics");

}

}

现在有一个MyMonitor类。假设没有向上转型,MyMonitor类代码如下:

package a.b;

public class MyMonitor {

public static void main(String[] args) {

       run(new LCDMonitor());

       run(new CRTMonitor());

       run(new PlasmaMonitor());

}

public static void run(LCDMonitor monitor) {

       monitor.displayText();

       monitor.displayGraphics();

}

public static void run(CRTMonitor monitor) {

       monitor.displayText();

       monitor.displayGraphics();

}

public static void run(PlasmaMonitor monitor) {

       monitor.displayText();

       monitor.displayGraphics();

}

}

可能你已经意识到上述代码有很多重复代码,而且也不易维护。有了向上转型,代码可以更为简洁:

package a.b;

public class MyMonitor {

public static void main(String[] args) {

       run(new LCDMonitor());                     //向上转型

       run(new CRTMonitor());                     //向上转型

       run(new PlasmaMonitor());            //向上转型

}

public static void run(Monitor monitor) { //父类实例作为参数

       monitor.displayText();

       monitor.displayGraphics();

}

}

我们也可以采用接口的方式,例如:

package a.b;

public interface Monitor {

abstract void displayText();

abstract void displayGraphics();

}

将液晶显示器类LCDMonitor稍作修改:

package a.b;

public class LCDMonitor implements Monitor {

public void displayText() {

       System.out.println("LCD display text");

}

public void displayGraphics() {

       System.out.println("LCD display graphics");

}

}
登录后复制

2 向下转型(父类转型成子类)

A类:

package a.b;

public class A {

void aMthod() {

       System.out.println("A method");

}

}

A的子类B:

package a.b;

public class B extends A {

void bMethod1() {

       System.out.println("B method 1");

}

void bMethod2() {

       System.out.println("B method 2");

}

}

C类:

package a.b;

public class C {

     public static void main(String[] args) {

            A a1 = new B(); // 向上转型

            a1.aMthod();    // 调用父类aMthod(),a1遗失B类方法bMethod1()、bMethod2()

            B b1 = (B) a1; // 向下转型,编译无错误,运行时无错误

            b1.aMthod();    // 调用父类A方法

            b1.bMethod1(); // 调用B类方法

            b1.bMethod2(); // 调用B类方法

            A a2 = new A();

            B b2 = (B) a2; // 向下转型,编译无错误,运行时将出错

            b2.aMthod();

            b2.bMethod1();

            b2.bMethod2();

     }

}

从上面的代码我们可以得出这样一个结论:向下转型需要使用强制转换。运行C程序,控制台将输出:

Exception in thread "main" java.lang.ClassCastException: a.b.A cannot be cast to a.b.B at
                a.b.C.main(C.java:14)

A method

A method

B method 1

B method 2
登录后复制

其实B b2 = (B) a2处的向下转型代码后的注释已经提示你将发生运行时错误。为什么前一句向下转型代码可以,而后一句代码却出错?这是因为a1指向一个子类B的对象,所以子类B的实例对象b1当然也可以指向a1。而a2是一个父类对象,子类对象b2不能指向父类对象a2。那么如何避免在执行向下转型时发生运行时ClassCastException异常?使用5.7.7节学过的instanceof就可以了。我们修改一下C类的代码:

A a2 = new A();

if (a2 instanceof B) {

B b2 = (B) a2;

b2.aMthod();

b2.bMethod1();

b2.bMethod2();

}
登录后复制

这样处理后,就不用担心类型转换时发生ClassCastException异常了。

以上就是Java向上转型和向下转型的使用介绍(附代码)的详细内容,更多请关注php中文网其它相关文章!

智能AI问答
PHP中文网智能助手能迅速回答你的编程问题,提供实时的代码和解决方案,帮助你解决各种难题。不仅如此,它还能提供编程资源和学习指导,帮助你快速提升编程技能。无论你是初学者还是专业人士,AI智能助手都能成为你的可靠助手,助力你在编程领域取得更大的成就。
来源:segmentfault网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
关于CSS思维导图的课件在哪? 课件
凡人来自于2024-04-16 10:10:18
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习
PHP中文网抖音号
发现有趣的

Copyright 2014-2024 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号