2010-01-20 74 views

回答

9

有时候你会对所有继承类需要设置的实例变量进行一些常见的初始化。当你扩展它时,你会实例化一个抽象类,而具体类有一个构造函数,它将提供参数给抽象类的构造函数。

+2

一个例子是javax.swing.AbstractAction – 2010-01-20 23:25:43

5

它们仍然可以由继承自其中的类的构造函数调用,从而使得代码重构在抽象类中具有构造函数很有用。

3

如果您在抽象类中有未初始化的最终字段,则需要在构造函数中初始化它们。

E.g.

abstract class A { 
    final int x; 
} 

不会编译而没有分配给x构造。

3

如果你的类没有声明一个构造函数,那么javac会为你创建一个无参数,无所事事的构造函数。然后,当你的子类被初始化时,它会调用生成的无操作构造函数,并且生活很好。

但是,如果你的类声明了任何构造函数,javac将不会为你创建一个构造函数。在这种情况下,子类构造函数需要显式调用父类的构造函数。否则,您将无法初始化父类的成员,如上面的答案所述。

2

抽象类的构造函数由子类使用(使用super(params)从子类构造函数中调用)。

您应该使这些构造函数protected清楚。

2

您不实例化抽象类,但构造函数在实例化子类时调用。

使用可能是初始化常见的属性,即。

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] 
1

去重复常识/行为。

E.g.一辆汽车:你所有的汽车将由一个车身和四个车轮和一个发动机构成。所以你通过调用Body(),Wheel(int x),Engine()等函数,在抽象Car类的构造函数中完成这部分构造。每个特定的汽车类都会有他们自己的Body(),Wheel()和Engine()的实现 - 但他们都会按照相同的步骤从它们中构建汽车,所以不需要在每个类中重复这些步骤类。在这种情况下,你可以在祖先中实现这个共同的行为。

-1

我同意,构造函数是假设会有实例创建的。如果你有很多通用的代码,你可以考虑创建一个构造函数,但是把它放在一个init()方法中会好很多。

+1

这是不好的建议,然后每个Inheirting类都需要记得调用super。init()并且它变得很乱,这是非标准的,非常糟糕的建议。 – 2010-01-21 18:15:55

相关问题