抽象类可继承实体类(要有明确的构造方法),这句话该怎么理解?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了抽象类可继承实体类(要有明确的构造方法),这句话该怎么理解?相关的知识,希望对你有一定的参考价值。

请高手解释清楚一点,举个例子最好

参考技术A 抽象类可以extends实体类。其实这就是类之间正常的继承关系。关于构造方法的说明,请看下例:
public class Test1
// 本例中所有类的父类
class A
public A() // 这是一个无参构造函数。如果不写这个构造函数,则编译器默认为具有这个构造函数。
public void println()
System.out.println("我是A的子类或对象,但不是B的子类。");


// A1类是A的子类
class A1 extends A
// 这里没有写构造函数,则编译器默认为具有一个无参构造函数。

// B是A1的子类,而且它是抽象类,具有抽象方法getName。并且复写了println方法
abstract class B extends A1
public B()// 这是一个无参构造函数。如果不写这个构造函数,则编译器默认为具有这个构造函数。
super(); // 它继承了A1,那么此构造函数第一句必须调用父类的构造方法。如果构造函数中没写这句,则编译器默认为调用了父类的无参构造方法。
// 如果父类没有无参构造函数,则必须显式调用父类的构造函数。

public abstract String getName();
public void println()
System.out.println("我是B的子类,我的名字叫:" + getName());


// B1是B的子类,实现了抽象方法getName
class B1 extends B
// 这里没有写构造函数,则编译器默认为具有一个无参构造函数;由于它是一个类的子类,所以默认构造方法中的第一句默认为调用父类的构造方法。
public String getName()
return "B1";



public void doRun()
A b1 = new B1();
// 以内部类的方式构造对象
A b2 = new B()
public String getName()
return "B2";

;
A a = new A();
A a1 = new A1();
b1.println();
b2.println();
a.println();
a1.println();

public static void main(String args[])
Test1 t = new Test1();
t.doRun();

本回答被提问者采纳

抽象类是否可继承实体类

问:抽象类是否可继承实体类

答:抽象类是可以继承实体类,但前提是实体类必须有明确的构造函数。

 -------------------

答案很明确,可以继承。其实从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只能够供内部类继承)

所以说这句话“实体类必须有明确的构造函数”的实际含义:

1.没写构造器的,那是拥有默认无参公有构造函数的,子类可以什么都不写,让默认构造器去调用它。这是最初那两行代码的情况。

2.写了子类可访问的无参构造器的,也是一样,子类里可以什么都不写,用默认机制调用。

3.写了有参构造器却没写无参构造器的,父类里没有子类可访问的无参构造器,子类必须在子类构造器里的第一句写明,调用父类有参构造器,并把参数传进去。

4.声明为final的以及所有构造器都不在子类访问权限之内的类无法继承

其实只要是在类的继承中,无论抽象还是实体,都需要符合这个规则的。在这个继承试验中随时删掉或是加上abstract的前缀,结果都没有变化。
所以说之前那句话的清楚写法应该是“可以继承,但是和实体类的继承一样,也要求父类可继承,并且拥有子类可访问到的构造器。”

以上是关于抽象类可继承实体类(要有明确的构造方法),这句话该怎么理解?的主要内容,如果未能解决你的问题,请参考以下文章

15接口是否可继承接口?抽象类是否可实现(implements)接口?抽象类是否可继承具体类(concreteclass)?抽象类中是否可以有静态的main方法?

Java面试题60 接口是否可继承接口? 抽象类是否可实现(implements)接口? 抽象类是否可继承具体类(concrete class)? 抽象类中是否可以有静态的main方法?

抽象类

接口和抽象类的区别

接口是不是可继承接口? 抽象类是不是可实现(implements)接口? 抽象类是不是可继承实体类(concrete class)?

关于类抽象类和接口的继承关系