- 浏览: 148760 次
- 性别:
- 来自: 上海
文章分类
转: http://blog.csdn.net/ckw1988/article/details/4639514
一道java 常见面试题,网上找到的几乎每个 java 面试笔试题大全或集锦里都能找到这道题。
题目如下:
问: 抽象类是否可继承实体类 (concrete class)
答: 抽象类是可以继承实体类,但前提是实体类必须有明确的构造函数
-------------------
答案很明确,可以继承。其实从Object就是个实体类,java的API文档里,每个抽象类的条目里都明确写着直接或间接继承自Object,所以这点是没有疑问的。
关键在于这答案里所说的“前提是实体类必须有明确的构造函数”一句,是什么意思。
一般学习者会写的简单试验代码:
class A{}
abstract class B extends A{}
结果完全正常,编译通过。似乎和“实体类必须有明确的构造函数”完全没有关系。
这个问题涉及到两个个基础知识:
1.
所有的class都必须有一个构造方法,如果你没有在代码里声明构造方法,系统会自动给你生成一个公有无参的构造方法。而只要你自己声明了一个构造方法,无论有参无参,私有公有,系统就不再帮你生成默认无参构造器了。
2.
所有的子类构造器都要求在第一行代码中调用父类构造器,如果不写,系统默认去调用父类的无参构造器。
所以,如果把系统默认配给的方法也算进去,class A{}的代码实际上是
class A{
public A(){}
}
B继承 A 的时候,则是
abstract class B extends A{
public B(){
super();
}
}
要试验出这继承规则的内部情况,也很简单,在最上面那个简单试验代码里,加上个私有构造器,有参无参都行。
class A{
private A(){}
}
这个时候,如基础知识(1) 中所说,系统不再给你默认无参构造器, B的构造器根据(2)中的规则去调用super(),却找不到A的无参构造器,所以导致abstract class B extends A{} 编译不能通过。(因为A中没有任何构造器可供子类调用,其实这个时候A只能够供内部类继承,我用的Eclipse的3.4版本会建议给B改名,但是这解决不了这个问题。)
现在,你应该了解了资料给的那句语焉不详的“实体类必须有明确的构造函数”的含义:
1.没写构造器的,那是拥有默认无参公有构造函数的,子类可以什么都不写,让默认构造器去调用它。这是最初那两行代码的情况。
2.写了子类可访问的无参构造器的,也是一样,子类里可以什么都不写,用默认机制调用。
3.写了 有参构造器却没写无参构造器的,父类里没有子类可访问的无参构造器,子类必须在子类构造器里的第一句写明,调用父类有参构造器,并把参数传进去。
4.声明为final的以及所有构造器都不在子类访问权限之内的类无法继承
其实只要是在类的继承中,无论抽象还是实体,都需要符合这个规则的。在这个继承试验中随时删掉或是加上abstract的前缀,结果都没有变化。个人觉得“实体类必须有明确的构造函数”一句实在是无法把这个情况表达清楚,所以广大求职者还是写得清楚些好。
我喜欢的写法是“可以继承,但是和实体类的继承一样,也要求父类可继承,并且拥有子类可访问到的构造器。”
一道java 常见面试题,网上找到的几乎每个 java 面试笔试题大全或集锦里都能找到这道题。
题目如下:
问: 抽象类是否可继承实体类 (concrete class)
答: 抽象类是可以继承实体类,但前提是实体类必须有明确的构造函数
-------------------
答案很明确,可以继承。其实从Object就是个实体类,java的API文档里,每个抽象类的条目里都明确写着直接或间接继承自Object,所以这点是没有疑问的。
关键在于这答案里所说的“前提是实体类必须有明确的构造函数”一句,是什么意思。
一般学习者会写的简单试验代码:
class A{}
abstract class B extends A{}
结果完全正常,编译通过。似乎和“实体类必须有明确的构造函数”完全没有关系。
这个问题涉及到两个个基础知识:
1.
所有的class都必须有一个构造方法,如果你没有在代码里声明构造方法,系统会自动给你生成一个公有无参的构造方法。而只要你自己声明了一个构造方法,无论有参无参,私有公有,系统就不再帮你生成默认无参构造器了。
2.
所有的子类构造器都要求在第一行代码中调用父类构造器,如果不写,系统默认去调用父类的无参构造器。
所以,如果把系统默认配给的方法也算进去,class A{}的代码实际上是
class A{
public A(){}
}
B继承 A 的时候,则是
abstract class B extends A{
public B(){
super();
}
}
要试验出这继承规则的内部情况,也很简单,在最上面那个简单试验代码里,加上个私有构造器,有参无参都行。
class A{
private A(){}
}
这个时候,如基础知识(1) 中所说,系统不再给你默认无参构造器, B的构造器根据(2)中的规则去调用super(),却找不到A的无参构造器,所以导致abstract class B extends A{} 编译不能通过。(因为A中没有任何构造器可供子类调用,其实这个时候A只能够供内部类继承,我用的Eclipse的3.4版本会建议给B改名,但是这解决不了这个问题。)
现在,你应该了解了资料给的那句语焉不详的“实体类必须有明确的构造函数”的含义:
1.没写构造器的,那是拥有默认无参公有构造函数的,子类可以什么都不写,让默认构造器去调用它。这是最初那两行代码的情况。
2.写了子类可访问的无参构造器的,也是一样,子类里可以什么都不写,用默认机制调用。
3.写了 有参构造器却没写无参构造器的,父类里没有子类可访问的无参构造器,子类必须在子类构造器里的第一句写明,调用父类有参构造器,并把参数传进去。
4.声明为final的以及所有构造器都不在子类访问权限之内的类无法继承
其实只要是在类的继承中,无论抽象还是实体,都需要符合这个规则的。在这个继承试验中随时删掉或是加上abstract的前缀,结果都没有变化。个人觉得“实体类必须有明确的构造函数”一句实在是无法把这个情况表达清楚,所以广大求职者还是写得清楚些好。
我喜欢的写法是“可以继承,但是和实体类的继承一样,也要求父类可继承,并且拥有子类可访问到的构造器。”
发表评论
-
Java-动态语言和静态语言
2014-06-25 10:40 612什么是动态语言和静态语言?http://haohetao.i ... -
hibernate 乐观锁与悲观锁使用
2014-05-27 10:57 319http://www.blogjava.net/baoyaer ... -
servlet什么时候被实例化?
2014-03-25 10:29 701http://blog.csdn.net/ji_ju/arti ... -
Struts2数据传输的背后机制:ValueStack(值栈)
2014-03-25 08:49 508http://blog.csdn.net/li_tengfei ... -
Spring中常用事务类型
2014-03-24 17:22 371PROPAGATION_REQUIRED--支持当前事务,如果 ... -
JAVA多线程--Runnable和Thread的区别
2014-03-24 14:17 520转载:http://blog.csdn.net/wwww198 ... -
JAVA中堆栈和内存分配
2014-03-19 09:32 558转:http://www.2cto.com/kf/20 ... -
abstract class和interface有什么区别?
2014-03-18 08:29 599转:http://java.itcast.cn/new ... -
深入Java集合学习系列:HashMap的实现原理
2014-03-18 08:34 316转:http://zhangshixi.iteye.com/b ... -
JAVA多线程--sleep和wait的区别
2014-03-17 16:30 5011、这两个方法来自不同的类分别是,sleep来自Thread类 ... -
Spring动态代理
2014-03-17 11:11 705Spring代码分析一:加载与初始化 http://www. ... -
Request的getParameter和getAttribute方法的区别
2013-12-27 10:39 601原文:http://blog.sina.com.cn/s/ ... -
struts2
2013-12-02 20:30 502ActionContext ServletActionCont ... -
Java集合比较器总结
2013-11-21 15:40 1666一:Java 集合: 对于什么是集合我想不多言了,简单点理 ... -
javascript中 visibility和display的区别
2013-11-13 15:39 612visibility属性用来确定元素是显示还是隐藏的,这用vi ... -
java中import机制(指定import和import *的区别)
2013-10-30 09:36 656http://blog.csdn.net/shuwei003/ ... -
sql执行顺序
2014-05-27 10:52 4931.查询中用到的关键词主要包含六个,并且他们的顺序依次为 s ... -
造成死锁的原因和解决方案
2013-10-17 14:17 471http://blog.csdn.net/superbsoft ... -
Java对Map中的值进行排序
2013-08-28 11:08 2206Map<String, Integer> ma ... -
遍历Map的四种方法
2013-08-05 10:28 625public static void main(Strin ...
相关推荐
抽象类是否可继承实体类 - 开心的日志 - 轻松一刻学习
一个student类,lectureTeatre类,继承抽象module类,通过继承来实现接口
1.继承及继承实例 2.方法重写(Overwrite) 3.super关键字 4.方法重载(Overload) 5.final修饰符 6.abstract修饰符 7.抽象类 8.接口 9.接口和抽象类对比 10.接口和抽象类使用场合实例 11.总结
采用普通类,接口,和抽象类实现单继承和多继承增,删,改,查,本人做的绝对完完善!!
一个使用了接口,抽象类,继承的JAVA类,模拟了计算机的组装过程
类的继承、抽象类、虚方法实现,每个提供一个例子,简单易懂
Java抽象类和接口和继承之间关系 Java抽象类和接口和继承之间关系
编写程序计算长方体、圆柱体和球的表面积和体积。要求先定义一个抽象类Shape如下:使用Shape类派生出长方体类、圆柱体类、球类,在这些类里分别实现继承的纯虚函数。使用如下代码测试运行。
抽象类_接口_多态_继承整合案例.。
这个文档总结概括了继承和抽象类的相关知识以及需要注意的事项
\\java类、抽象类、接口、继承和对象解析 .doc
Java程序设计课程实验9-继承和抽象类Java程序设计课程实验9-继承和抽象类Java程序设计课程实验9-继承和抽象类Java程序设计课程实验9-继承和抽象类Java程序设计课程实验9-继承和抽象类Java程序设计课程实验9-继承和...
抽象类与抽象方法由abstract修饰 ...1.抽象类不能被实例化,只能被其他类继承 2.继承抽象类的子类必须把抽象类中的所有抽象成员都重写(实现)(除非子类也是抽象类。) 3.抽象类就是为了重写→多态。
JAVA 继承基本类、抽象类、接口区别与联系
类、抽象类、接口、继承和对象(java).doc类、抽象类、接口、继承和对象(java).doc类、抽象类、接口、继承和对象(java).doc类、抽象类、接口、继承和对象(java).doc类、抽象类、接口、继承和对象(java).doc类、抽象类...
这个实例介绍了“继承,虚函数,抽象类”的相关用法和注意事项,里面有代码和一些知识点,方便新手学习和理解这些概念,相当于书与代码的结合。
抽象类和接口的区别 在Java语言中, abstract class 和interface 是支持抽象类定义的两种机制。正是由于这两种机制的存在,才赋予了Java强大的 面向对象能力。abstract class和interface之间在对于抽象类定义的支持...
抽象类不能实现多继承。 • 接口只能定义抽象规则;抽象类既可以定义规则,还可能提供已实现的成员。 • 接口是一组行为规范;抽象类是一个不完全的类,着重族的概念。 • 接口可以用于支持回调;抽象类...
在这一系列“跳水在面向对象编程”的这篇...抽象类起到多态性和继承一个不同的和非常有趣的角色。我们将讨论抽象类与我们的动手实验和理论作为解释什么输出我们得到的所有方面。我们也将列出下来点,记得在文章的结尾。
“抽象类允许(但不要求)抽象类包含抽象成员”。但是一个抽象类里不写抽象方法就没有意义了,既然如此,还不如直接写个普通类? 在一个抽象类里可以不声明抽象方法,这在语法上是没问题的,但实际来说,这样是没有...