java面试题1 牛客:A派生出子类B,B派生出子类C,并且在java源代码中有如下声明:

java面试题1 牛客:A派生出子类B,B派生出子类C,并且在java源代码中有如下声明:懵逼树上懵逼果 懵逼树下你和我第一题 单选题 A 派生出子类 B B 派生出子类 C 并且在 java 源代码中有如下声明 1 2 3 Aa0 newA Aa1 newB Aa2 newC 以哪个说法是正确的 A 第 1 行 第 2 行和第 3 行的声明都是正确的 B 第 1 2 3 行都能通

懵逼树上懵逼果,懵逼树下你和我

第一题

 

[单选题]

A派生出子类B,B派生出子类C,并且在java源代码中有如下声明:

1

2

3

A a0=new A();

A a1=new B();

A a2=new C();

以哪个说法是正确的

A第1行,第2行和第3行的声明都是正确的 
 B第1,2,3行都能通过编译,但第2,3行运行时出错 
C第1,2行能通过编译,但第3行编译出错 
D只有第1行能通过编译

首先看到这个题,本人的确是有点懵逼的,我想着这玩意是选c吧,第一行代码肯定没得问题

然后第二行不是一个上转型对象,也是可以操作的。第三行也太秀了趴,中间跨了一个类直接再来哥上转型,这玩意肯定是有问题的。果断选c,然而很显然,我错了,当然看了一眼答案

然后我看看别人的解析

java面试题1 牛客:A派生出子类B,B派生出子类C,并且在java源代码中有如下声明:

java面试题1 牛客:A派生出子类B,B派生出子类C,并且在java源代码中有如下声明:

多说不说,打开了自己的idea

按照要求来

public class A { } 
public class B extends A { } 
public class C extends B { } 
public class D { public static void main(String[] args){ A a1=new A(); A a2=new B(); A a3=new C(); } } 

事实证明,没有报错,又回去看看上转型对象

向上转型

  我们在现实中常常这样说:这个人会唱歌。在这里,我们并不关心这个人是黑人还是白人,是成人还是小孩,也就是说我们更倾向于使用抽象概念“人”。再例如,麻雀是鸟类的一种(鸟类的子类),而鸟类则是动物中的一种(动物的子类)。我们现实中也经常这样说:麻雀是鸟。这两种说法实际上就是所谓的向上转型,通俗地说就是子类转型成父类。这也符合Java提倡的面向抽象编程思想。

public class A { public void a1() { System.out.println("Superclass"); } } 
public class B extends A { public void a1() { System.out.println("Childrenclass"); //覆盖父类方法 } public void b1(){} //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:

public class Monitor{ public void displayText() {} public void displayGraphics() {} } 

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

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的子类:

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的子类:

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类代码如下:

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(); } } 

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

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(); } } 

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

public interface Monitor { abstract void displayText(); abstract void displayGraphics(); } 

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

public class LCDMonitor implements Monitor { public void displayText() { System.out.println("LCD display text"); } public void displayGraphics() { System.out.println("LCD display graphics"); } } 

CRTMonitor、PlasmaMonitor类的修改方法与LCDMonitor类似,而MyMonitor可以不不作任何修改。

  可以看出,向上转型体现了类的多态性,增强了程序的简洁性。

向下转型

  子类转型成父类是向上转型,反过来说,父类转型成子类就是向下转型。但是,向下转型可能会带来一些问题:我们可以说麻雀是鸟,但不能说鸟就是麻雀。来看下面的例子:

public class A { void aMthod() { System.out.println("A method"); } } 

A的子类B:

public class B extends A { void bMethod1() { System.out.println("B method 1"); } void bMethod2() { System.out.println("B method 2"); } } 

C类:

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

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

A a2 = new A(); if (a2 instanceof B) { B b2 = (B) a2; b2.aMthod(); b2.bMethod1(); b2.bMethod2(); } 

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

所以答案为A

文章仅个人理解,来在各大网站。如有不合理之处,欢迎吐槽。

阅读目录(置顶)(长期更新计算机领域知识)https://blog.csdn.net/weixin_/article/details/

阅读目录(置顶)(长期更新计算机领域知识)https://blog.csdn.net/weixin_/article/details/

阅读目录(置顶)(长期科技领域知识)https://blog.csdn.net/weixin_/article/details/

歌谣带你看java面试题 https://blog.csdn.net/weixin_/article/details/

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/229893.html原文链接:https://javaforall.net

(0)
上一篇 2026年3月16日 下午3:37
下一篇 2026年3月16日 下午3:38


相关推荐

  • 大数据要学javaweb吗_大数据用学JAVA吗?

    大数据要学javaweb吗_大数据用学JAVA吗?谢邀学大数据没有必要报专门的Java班.学习大数据之前确实要先学习一点Java的内容,因为大数据和Java不是完全分裂的,大数据的开发语言中最重要的一种就是Java.学习Java主要包括四大块:Java基础(JavaSE),JavaWeb,Java框架(JavaEE),Java项目,但是学习大数据只是用Java作为编程语言,只要学习Java基础(JavaSE)就够了,至于后面的三块儿内容可以先…

    2022年5月8日
    61
  • tomcat的contextpath可以重复吗_tomcat deployment配置

    tomcat的contextpath可以重复吗_tomcat deployment配置本文章转载自https://www.cnblogs.com/yanan7890/p/8329163.htmltomcatserver.xmlcontextpath配置需要注意的事情在tomcat下放个war包,假如我是这样配置server.xml的,<ContextdocBase=”eggchina”path=”/yanan”reloadable=”true”sou…

    2025年12月15日
    4
  • 算法模型大全

    算法模型大全隐马尔可夫模型(HMM)http://baike.baidu.com/link?url=_NiQW91Kkdmyla_lyX1C78NVIXnzELO2l4Sr9e6FstHcss6ssmawwwZHXR7MZ_CP8ofgVTBQe-pOhmqZFx2qHKGMM(GaussianMixtureModel)-高斯混合模型http://baike.baidu.com/link?url=4zzM

    2022年6月23日
    29
  • Navicat 连接MySQL数据库出现错误:2059

    Navicat 连接MySQL数据库出现错误:2059Navicat连接MySQL数据库出现错误:2059-authenticationplugin’caching_sha2_password’的解决方法

    2022年8月31日
    3
  • input file样式设置

    input file样式设置需要提交input上传的文件等内容,所以需要form表单HTML代码 CSS样式#outData{ width:96%; background:#FFFFFF; height:100%; text-align:right; margin:0auto;}#upload{ display:inline-block; margin-top:5px

    2022年7月25日
    25
  • 成功的背后1

    成功的背后1

    2021年8月23日
    61

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号