`

抽象类可以继承实体类吗?

 
阅读更多

一道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类继承吧,掉了后半句。

分享到:
评论

相关推荐

    c++抽象类继承

    根据给定的信息,我们可以深入探讨C++中的抽象类与继承机制。下面将详细介绍如何通过抽象类和继承在C++中实现特定的功能。 ### 概述 在这个示例中,我们有三个具体的类:`Student`、`Lecture` 和 `Module`,它们都...

    抽象类是否可继承实体类 - 开心的日志

    抽象类是否可继承实体类 - 开心的日志 - 轻松一刻学习

    抽象类与适配器模式

    抽象类不能直接创建实例,因为它们代表了一种通用的概念,而非具体的实体。 2. **抽象类的实例化**: - 抽象类不能被实例化,这意味着我们不能使用`new`关键字创建抽象类的对象。抽象类的存在是为了被其他类继承,...

    JAVA中抽象类与接口的区别

    抽象类和接口都可以帮助达到这一目标,但通常接口更加灵活,因为一个类可以通过实现不同的接口来承担不同的职责。 ### 四、选择建议 当面临抽象类与接口的选择时,可以根据以下几点来进行决策: 1. **是否需要多...

    vehicle类_抽象类Vehicle_vehicle类_

    在这个场景中,我们将探讨如何使用C++来设计一个抽象类`Vehicle`,并从这个抽象类派生出具体的类`Car`和`Truck`。抽象类通常用于定义一个基类,它包含了一些共同的方法和属性,但不提供具体实现,而是由其子类去完成...

    抽象类与接口的区别

    这意味着一个类可以从多个接口继承行为,但在Java中只能继承一个抽象类。 - **方法实现**:抽象类可以包含具体的方法实现,而接口中的方法默认都是抽象的。这一点非常重要,因为它意味着接口更倾向于定义一种协议或...

    NIIT 抽象类代码

    4. **继承机制**:抽象类常作为其他类的基类,通过继承抽象类,子类可以获得抽象类的所有属性和方法,并可以扩展或重写它们。 5. **接口与抽象类的区别**:在某些语言中,如Java,抽象类和接口都是用于实现多态性。...

    学习笔记:抽象封装、继承、多态.doc

    - **抽象类继承**: 抽象类中可以定义抽象方法,子类继承后必须实现这些抽象方法。 #### 六、编码规范 **Java命名规范**: - 方法名和变量名首字母小写,其余单词首字母大写(camelCase)。 - 类名首字母大写,其余...

    详细解析抽象类和接口的区别

    - 抽象类倾向于表示“is-a”关系,比如一个`Animal`抽象类可以被`Dog`和`Cat`等具体类继承。 - 接口更多地表示“can-do”关系,如`Runnable`接口,表示一个类可以执行某个任务。 6. **实现方式:** - 继承抽象类...

    SSH集成+分页抽象类+自定义标签 == 分页数据效果

    例如,我们可以定义一个名为`BasePageService`的抽象类,其中包含`queryByPage()`方法,用于根据条件和分页参数执行SQL查询,并返回分页结果。业务服务层的其他类可以继承这个基类,重写必要的部分以满足特定需求。 ...

    Java中的类、抽象类和接口的区别和联系[参考].pdf

    3. 一个类可以继承一个抽象类,并实现多个接口。 4. 抽象类可以提供部分实现,而接口只定义行为,不提供实现。 5. 接口更强调“行为”,抽象类更倾向于“是什么”或“怎么样”。 在实际开发中,合理地使用类、抽象...

    java23.7.12-继承抽象多态

    2. **继承抽象类**:如果一个类继承了抽象类,那么要么这个类也必须是抽象类,要么实现所有抽象方法。 3. **接口与抽象类的区别**:接口全由抽象方法组成,而抽象类可以包含非抽象方法。一个类可以实现多个接口,但...

    面向对象抽象思维与java继承机制

    - **多继承的替代**:虽然Java不支持传统的多继承(一个类继承自多个父类),但它通过接口提供了类似的功能。接口可以被多个类实现,从而实现了某种形式的多继承。 - **扩展与重写**:子类不仅可以继承父类的所有非...

    Java 抽象类定义与方法实例详解

    6. **强制实现**:如果一个类继承自抽象类,它只需要实现抽象类中未实现的抽象方法;而如果一个类实现接口,它必须实现接口中的所有方法。 7. **构造器**:抽象类可以有构造器,用于初始化实例变量;接口不能有构造...

    java抽象类与接口的深入思考

    而使用抽象类,当需要增加新的抽象方法时,所有继承该抽象类的子类都需要进行相应的修改。 #### 总结 抽象类和接口在Java中都是重要的设计模式,它们各自有独特的特性和适用场景。正确理解和运用这两种机制对于...

    java/.net实体类代码生成器

    在对象关系映射(ORM)框架中,实体类是对数据库表的抽象,每个实体类对应数据库中的一个表,类中的属性对应表中的字段。例如,如果有一个名为"Employees"的数据库表,那么对应的Java实体类可能是这样的: ```java ...

    数据层 万能实体类方法

    这样,对于每个新的实体类,我们只需要继承`BaseRepository<T>`并传入对应的DbContext即可,无需编写具体的数据库操作代码。 在实际项目中,我们还可以根据需求扩展这些万能方法,比如添加分页查询、事务处理、性能...

    sql server实体类生成工具

    5. **继承与接口**:高级的实体类生成工具可能会提供基于继承的多表关联支持,比如基类包含公共属性,派生类包含特定表的属性。同时,也可能生成实现接口的类,这些接口可以用于数据访问的抽象。 6. **数据库操作**...

Global site tag (gtag.js) - Google Analytics