最近我看见有人问过这个问题。在此我想表达一下自己的观点。
根据面向对象中关于继承这个概念——子类继承父类所有的属性和方法。那么既然是所有的那么本人认为也应当也包括构造函数(方法)。
我先举一个C++的例子:
... {
private:
int p;
public:
Parent(void) : p(0)
...{
}
Parent(int i) : p(i)
...{
}
} ;
class Child : public Parent
... {
private:
int c;
public:
Child(void) : Parent(), c(0)
...{
// 在这里,创建Child对象时先构造父类域
}
Child(int i) : Parent(i + 1), c(i)
...{
// 同上
}
} ;
如何证明Child类继承了Parent类的两个构造函数呢?
由于构造函数非常特别,对它的调用就像是调用一个C函数一样,而不是利用对象来调用的(若不先构造对象哪儿来的对象?)。因此鉴于这份特殊性我们可以这么考虑:
将上述代码中class Child : public Parent——去掉“: public Parent”,我们可以编译试试,是否能成功。事实上正是因为Parent与Child有亲子关系,所以Child构造函数中可以调用Parent的构造函数先对其Parent域进行初始化。这个特点非常符合工程学——详见我的文章《我比起Java更喜欢C++的理由——语义》。
下面将贴出相应的Java代码:
private int p;
public Parent() ...{
p = 0;
}
public Parent(int i) ...{
p = i;
}
}
class Child extends Parent ... {
private int c;
public Child() ...{
super();
c = 0;
}
public Child(int i) ...{
super(i + 1);
c = i;
}
}
我们可以看到,在Java中可以利用super关键字来访问本类父类的构造方法。这样在一定程度上也消除了歧异性——比如你也可以在Child类中的某一个方法中这么写:Parent p = new Parent();而利用super()就表示了子类在初始化本类域前先初始化其父类域。这也可以证明在Java中子类继承父类构造方法,并且子类可以通过 super来访问父类的构造方法,只要父类的构造方法不是private。