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

互联网 19-3-19
本篇文章给大家带来的内容是关于Java向上转型和向下转型的使用介绍(附代码),有一定的参考价值,有需要的朋友可以参考一下,希望对你有所帮助。
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向上转型和向下转型的使用介绍(附代码)的详细内容,更多内容请关注技术你好其它相关文章!

来源链接:
免责声明:
1.资讯内容不构成投资建议,投资者应独立决策并自行承担风险
2.本文版权归属原作所有,仅代表作者本人观点,不代表本站的观点或立场
标签: java
上一篇:php获取远程图片并下载保存到本地的方法分析 下一篇:怎么使用JVM捕获Java异常?(附示例)

相关资讯