一道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的前缀,结果都没有变化。个人觉得“实体类必须有明确的构造函数”一句实在是无法把这个情况表达清楚,所以广大求职者还是写得清楚些好。
我喜欢的写法是“可
以继承,但是和实体类的继承一样,也要求父类可继承,并且拥有子类可访问到的构造器。”
我笔试的时候只答的“可以继承”。心想所有的类都从Object类继承吧,掉了后半句。
分享到:
相关推荐
抽象类是否可以继承实体类?:接口可以继承接口,抽象类可以实现接口,抽象类可以继承实体类,但有个条件,条件是,实体类必须要有明确的构造函数。 12. 构造器 Constructor 是否可以被继承?是否可以被 Override?...
抽象类是否可以继承实体类? * 接口可以继承接口 * 抽象类可以实现接口 * 抽象类可以继承实体类 13. a=10,b=15,在不用第三方变量的情况下,把 a,b 交换值? 可以使用 XOR 运算符来实现交换值: ``` a = a ^ b; ...
- 抽象类可以继承普通类(实体类),体现“is-a”的继承关系。 1.3 匿名内部类: - 匿名内部类可以继承其他类,也可以实现一个或多个接口。 - 在Swing编程中,匿名内部类常用来创建事件监听器,因为它们通常是为...
- 抽象类也可以继承实体类,只要实体类提供了适当的构造函数供抽象类使用。 #### 六、Java的Goto关键字 尽管`goto`是Java语言的保留关键字,但它并未在Java中使用。这是因为`goto`在很多情况下会导致代码难以理解...
在 .NET 中,接口可以继承接口,抽象类可以实现接口,抽象类也可以继承实体类,但实体类必须要有明确的构造函数。 四、构造器和继承 构造器不能被继承,因此不能被重写(Overriding),但可以被重载(Overloading...
能够创建和使用接口,理解抽象类和密封类的区别,以及何时使用它们。 3. **泛型**:了解泛型的概念,如何在方法、类和接口中使用泛型,以及其在类型安全和代码重用上的优势。 4. **集合与数据结构**:熟悉List、...
抽象类可以有抽象方法和非抽象方法,类只能继承一个抽象类。 7. **构造函数的作用?** 构造函数用于初始化新创建的对象,通常与类同名且无返回值。Java允许定义有参数的构造器,以便在创建对象时传递初始值。 8. ...
抽象类与否可以实现实体类? 1. 接口可以继承接口。 2. 抽象类可以实现接口,只需要实现接口内所有方法就可以了。 3. 抽象类可以实现实体类。 八、一种“.java”源文献中与否可以包括多种类(非内部类)? 可以。...
抽象类可以包含方法实现,一个类只能继承一个抽象类,但可以提供更多的通用功能。接口强调功能规范,抽象类则更注重类的层次结构。 抽象类是含有抽象方法的类,它不能实例化,用于定义一种共同的行为模式,强制子类...
12. **接口与抽象类的关系**:接口可以继承接口,抽象类可以实现接口,但抽象类不能继承非抽象类(实体类)。 13. **交换a和b的值**:无需第三方变量,可以使用异或操作完成交换,`a = a ^ b; b = a ^ b; a = a ^ b...
ASP.NET 面试题库 本资源汇总了企业面试题库中...在 C# 中,接口可以继承其他接口,抽象类可以实现接口和继承其他抽象类或实体类。 13. 赋值操作 在 C# 中,可以使用临时变量来实现赋值操作,例如将 a 的值赋给 b。
接口用于多重继承,抽象类用于单一继承。 **3. Java类是否可以多继承?** Java类不支持多继承,但可以通过实现多个接口来达到类似的效果。 **4. Hashtable与HashMap的区别?** `Hashtable`是线程安全的,`HashMap`...
- **抽象类继承实体类**:抽象类可以从实体类继承,实体类需具备显式定义的构造函数。 #### 4. 构造器的继承与重写 - **构造器特性**:构造器不能被继承,因此也不能被重写。 - **重载**:构造器可以通过参数的...
- 抽象类可以继承实体类(非抽象类),但实体类必须有一个无参构造函数。 4. **构造器(Constructor)**: - 构造器不能被继承,因此不能被重写(Overriding),但可以被重载(Overloading)。 5. **线程同步**...
22. **接口与接口继承,抽象类与接口**:接口可以继承接口,抽象类可以实现接口,抽象类可以继承实体类。 23. **启动线程**:使用start()启动线程,run()直接执行。 24. **构造器不可override**:构造器不是方法,...
- 抽象类可以实现接口,但抽象类不能继承具体类(实体类)除非实体类有无参构造方法。 7. **Java中的goto**: - Java中没有实际使用goto语句,但它是一个保留关键字,可能未来版本会使用。 8. **启动线程的方式*...
22. **接口继承接口,抽象类实现接口,抽象类继承实体类**: - 接口可以继承接口。 - 抽象类可以实现接口。 - 抽象类可以继承实体类。 23. **启动线程**: - 使用`start()`方法启动线程,`run()`方法是线程执行...
- 抽象类可以继承非抽象类(实体类),但实体类必须有默认构造函数。 4. **构造器(Constructor)**: - 构造器不能被继承,也不能被覆盖(Override),但可以被重载(Overloading)。 5. **线程同步**: - 一...
- 实体类(非抽象)可以被抽象类继承,但抽象类必须有一个无参数的构造函数。 4. **构造器的特性** - 构造器不能被继承,因此不能被重写,但可以被重载(即构造函数可以有多个,有不同的参数列表)。 5. **线程...