【发布时间】:2010-01-20 23:14:07
【问题描述】:
我想知道抽象类的构造函数有什么用途;由于我们不实例化抽象类,为什么我们需要这样的构造函数?
【问题讨论】:
标签: java constructor abstract-class
我想知道抽象类的构造函数有什么用途;由于我们不实例化抽象类,为什么我们需要这样的构造函数?
【问题讨论】:
标签: java constructor abstract-class
有时,您需要对所有继承类都需要设置的实例变量进行一些通用初始化。扩展抽象类时确实会实例化一个抽象类,并且该具体类具有一个构造函数,该构造函数将向抽象类的构造函数提供参数。
【讨论】:
它们仍然可以被从该类继承的类的构造函数调用,从而使代码重构成为在抽象类中具有构造函数的一个很好的用途。
【讨论】:
如果您在抽象类中有未初始化的最终字段,则需要在构造函数中对其进行初始化。
例如
abstract class A {
final int x;
}
如果没有分配给x 的构造函数,将无法编译。
【讨论】:
如果你的类没有声明构造函数,javac 会为你创建一个无参数、什么都不做的构造函数。然后,当您的子类被初始化时,它将调用生成的无操作构造函数,并且生活很好。
但是,如果你的类声明了任何构造函数,javac 不会为你创建一个。在这种情况下,子类构造函数需要显式调用父类的构造函数。否则,您将无法初始化父类的成员,如上述答案所述。
【讨论】:
子类使用抽象类的构造函数(使用 super(params) 从子类构造函数调用)。
您应该将这些构造函数设为protected 以明确这一点。
【讨论】:
您不实例化抽象类,但在实例化子类时会调用构造函数。
用途可能是初始化公共属性,即。
import java.util.List;
import java.util.ArrayList;
abstract class BaseClass {
protected List list; // visible from subclasses
public BaseClass() {
System.out.println("to abstract...");
// common initialization to all subclasses
list = new ArrayList();
list.add("a");
list.add("a");
list.add("a");
}
}
class ConcreteClass extends BaseClass {
public ConcreteClass(){
// The list is initialized already
System.out.println("now it is concrete and the list is: = "+ this.list );
}
}
class TestAbstractClass {
public static void main( String [] args ) {
BaseClass instance = new ConcreteClass();
}
}
输出
$ java TestAbstractClass
to abstract...
now it is concrete and the list is: = [a, a, a]
【讨论】:
重复删除常见知识/行为。
例如一辆汽车:你所有的汽车都将由一个车身、四个轮子和一个发动机构成。因此,您可以通过调用 Body()、Wheel(int x)、Engine() 等函数在抽象 Car 类的构造函数中完成这部分构造。每个特定的汽车类都有自己的 Body()、Wheel() 和 Engine() 实现——但它们都将执行相同的步骤来构造汽车,因此无需在每个步骤中重复这些步骤类。在这种情况下,您在祖先中实现该常见行为。
【讨论】:
我同意,构造函数是在假设存在实例的情况下创建的。如果您有很多通用代码,您可以考虑创建一个构造函数,但最好将其放入 init() 方法中。
【讨论】: