- 浏览: 154064 次
- 性别:
- 来自: 上海
文章分类
转: 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 668什么是动态语言和静态语言?http://haohetao.i ... -
hibernate 乐观锁与悲观锁使用
2014-05-27 10:57 371http://www.blogjava.net/baoyaer ... -
servlet什么时候被实例化?
2014-03-25 10:29 760http://blog.csdn.net/ji_ju/arti ... -
Struts2数据传输的背后机制:ValueStack(值栈)
2014-03-25 08:49 538http://blog.csdn.net/li_tengfei ... -
Spring中常用事务类型
2014-03-24 17:22 394PROPAGATION_REQUIRED--支持当前事务,如果 ... -
JAVA多线程--Runnable和Thread的区别
2014-03-24 14:17 544转载:http://blog.csdn.net/wwww198 ... -
JAVA中堆栈和内存分配
2014-03-19 09:32 586转:http://www.2cto.com/kf/20 ... -
abstract class和interface有什么区别?
2014-03-18 08:29 638转:http://java.itcast.cn/new ... -
深入Java集合学习系列:HashMap的实现原理
2014-03-18 08:34 369转:http://zhangshixi.iteye.com/b ... -
JAVA多线程--sleep和wait的区别
2014-03-17 16:30 5321、这两个方法来自不同的类分别是,sleep来自Thread类 ... -
Spring动态代理
2014-03-17 11:11 729Spring代码分析一:加载与初始化 http://www. ... -
Request的getParameter和getAttribute方法的区别
2013-12-27 10:39 625原文:http://blog.sina.com.cn/s/ ... -
struts2
2013-12-02 20:30 565ActionContext ServletActionCont ... -
Java集合比较器总结
2013-11-21 15:40 1702一:Java 集合: 对于什么是集合我想不多言了,简单点理 ... -
javascript中 visibility和display的区别
2013-11-13 15:39 642visibility属性用来确定元素是显示还是隐藏的,这用vi ... -
java中import机制(指定import和import *的区别)
2013-10-30 09:36 715http://blog.csdn.net/shuwei003/ ... -
sql执行顺序
2014-05-27 10:52 5201.查询中用到的关键词主要包含六个,并且他们的顺序依次为 s ... -
造成死锁的原因和解决方案
2013-10-17 14:17 543http://blog.csdn.net/superbsoft ... -
Java对Map中的值进行排序
2013-08-28 11:08 2246Map<String, Integer> ma ... -
遍历Map的四种方法
2013-08-05 10:28 650public static void main(Strin ...
相关推荐
抽象类是否可继承实体类 - 开心的日志 - 轻松一刻学习
`Student` 类继承自 `UniversityObject`,并实现了 `getSummary()` 函数。该函数返回学生的注册号和姓名组成的字符串。构造函数接受两个字符串参数,分别用于初始化 `name` 和 `register_str` 成员变量。通过这种...
在这个系统中,"表面积和体积_抽象类Shape_shape类继承_"这个主题涉及到的是OOP中的一个重要概念——抽象类和类的继承。 首先,让我们来理解抽象类(Abstract Class)。抽象类是一种特殊的类,它不能被实例化,主要...
1.继承及继承实例 2.方法重写(Overwrite) 3.super关键字 4.方法重载(Overload) 5.final修饰符 6.abstract修饰符 7.抽象类 8.接口 9.接口和抽象类对比 10.接口和抽象类使用场合实例 11.总结
"Java抽象类和接口和继承之间关系" Java抽象类和接口是两种不同的概念,它们之间存在着继承关系。在Java中,抽象类(abstract class)和接口(interface)都是用来描述对象的行为和状态的,但它们之间有着明显的...
本主题将深入探讨如何使用普通类、接口和抽象类来实现这些继承方式,并应用到“增、删、改、查”(CRUD,Create, Read, Update, Delete)操作中。 首先,单继承是指一个子类只能继承一个父类的特性。这种方式使得...
3. **继承性**:抽象类可以被其他类继承,一个类可以继承多个抽象类的功能(通过多层继承实现)。 4. **方法实现**:抽象类中的非抽象方法具有实际的实现,而抽象方法需要由子类提供实现。 #### 四、接口 **定义**...
抽象类是一种不能被实例化的类,它用于定义共同接口,供其他类继承。在C#中,我们使用`abstract`关键字声明抽象类。例如,我们可能有一个`Animal`抽象类,其中包含一个抽象方法`MakeSound()`: ```csharp public ...
在编程世界中,继承、虚函数和抽象类是面向对象编程(OOP)中的核心概念。这三者共同构建了类的层次结构,使得代码更加模块化,易于维护和扩展。接下来,我们将深入探讨这三个概念及其相关用法。 首先,**继承**是...
一个使用了接口,抽象类,继承的JAVA类,模拟了计算机的组装过程
Java 类、抽象类、接口和继承是面向对象编程的核心概念,它们构成了 Java 语言的基石。在 Java 中,类是用来封装数据和行为的结构,而对象则是类的实例,具有具体的属性和行为。 1. **类与对象的区别** 类是模板...
在Java编程语言中,抽象类和接口是两种重要的面向对象设计概念,它们允许我们定义规范,供其他类去实现或继承。在这个练习中,我们将深入理解这两种机制,并通过实际的代码示例和注释来加深理解。 首先,让我们讨论...
- **抽象类**:一个类只能继承一个抽象类。 - **接口**:一个类可以实现多个接口。 这种差异意味着接口更适合用于定义对象间的行为规范,而抽象类则适合定义一组紧密相关的类的共同属性和行为的基础框架。 ##### ...
- 如果一个类继承了抽象类,那么它必须实现抽象类中的所有抽象方法,除非这个子类也被声明为抽象类。这是Java编译器强制的规定,确保所有的抽象方法都有实现。 4. **接口与抽象类的区别**: - 接口是Java中另一种...
在这个例子中,`Dog`类继承了`Animal`抽象类,并提供了`MakeSound`方法的具体实现。使用`override`关键字确保了`Dog`类覆盖了`Animal`类中的抽象方法。 C#中的抽象类还有以下几点需要注意: 1. **抽象类不能被实例...
这个文档总结概括了继承和抽象类的相关知识以及需要注意的事项
抽象类与抽象方法由abstract修饰 ...1.抽象类不能被实例化,只能被其他类继承 2.继承抽象类的子类必须把抽象类中的所有抽象成员都重写(实现)(除非子类也是抽象类。) 3.抽象类就是为了重写→多态。
总的来说,虽然Java中的抽象类不能直接实例化,但我们可以通过继承并实现其抽象方法,或者利用字节码工具和注解处理器在运行时或编译时动态生成新的类来间接达到实例化抽象类的目的。这样的设计允许我们创建更加灵活...
在Java编程语言中,抽象类是一种特殊的类,它不能被实例化,但可以被其他类继承。这个实验“关于抽象类的Java实验Animal”旨在帮助我们理解如何在Java中使用抽象类以及多态性概念。在这个实验中,我们定义了一个名为...