Pab*_*dez 179 java inheritance constructor
我想知道为什么java构造函数不会被继承?你知道什么时候有这样的课:
public class Super {
public Super(ServiceA serviceA, ServiceB serviceB, ServiceC serviceC){
this.serviceA = serviceA;
//etc
}
}
Run Code Online (Sandbox Code Playgroud)
稍后当你继承时Super,java会抱怨没有定义默认的构造函数.解决方案显然是这样的:
public class Son extends Super{
public Son(ServiceA serviceA, ServiceB serviceB, ServiceC serviceC){
super(serviceA,serviceB,serviceC);
}
}
Run Code Online (Sandbox Code Playgroud)
这段代码是重复的,而不是干的和无用的(恕我直言)...所以这又带来了问题:
为什么java不支持构造函数继承?不允许这种继承有什么好处吗?
Jon*_*eet 197
假设构造函数中继承......然后,因为每个类最终从对象派生,每类将结束与一个参数的构造函数.这是个坏主意.你到底想要什么:
FileInputStream stream = new FileInputStream();
Run Code Online (Sandbox Code Playgroud)
去做?
现在可能应该有一种方法可以轻松创建相当常见的"传递"构造函数,但我不认为它应该是默认值.构造子类所需的参数通常不同于超类所需的参数.
Dav*_*ria 30
当你从Super继承时,这就是现实中发生的事情:
public class Son extends Super{
// If you dont declare a constructor of any type, adefault one will appear.
public Son(){
// If you dont call any other constructor in the first line a call to super() will be placed instead.
super();
}
}
Run Code Online (Sandbox Code Playgroud)
所以,这就是原因,因为你必须调用你的独特构造函数,因为"超级"没有默认构造函数.
现在,试图猜测为什么Java不支持构造函数继承,可能是因为构造函数只有在谈论具体实例时才有意义,而当你不知道它是如何定义的时候你不应该创建一个实例(通过多态性).
gus*_*afc 11
因为构造子类对象可能以与构造超类的方式不同的方式完成.您可能不希望子类的客户端能够调用超类中可用的某些构造函数.
一个愚蠢的例子:
class Super {
protected final Number value;
public Super(Number value){
this.value = value;
}
}
class Sub {
public Sub(){ super(Integer.valueOf(0)); }
void doSomeStuff(){
// We know this.value is an Integer, so it's safe to cast.
doSomethingWithAnInteger((Integer)this.value);
}
}
// Client code:
Sub s = new Sub(Long.valueOf(666L)): // Devilish invocation of Super constructor!
s.doSomeStuff(); // throws ClassCastException
Run Code Online (Sandbox Code Playgroud)
甚至更简单:
class Super {
private final String msg;
Super(String msg){
if (msg == null) throw new NullPointerException();
this.msg = msg;
}
}
class Sub {
private final String detail;
Sub(String msg, String detail){
super(msg);
if (detail == null) throw new NullPointerException();
this.detail = detail;
}
void print(){
// detail is never null, so this method won't fail
System.out.println(detail.concat(": ").concat(msg));
}
}
// Client code:
Sub s = new Sub("message"); // Calling Super constructor - detail is never initialized!
s.print(); // throws NullPointerException
Run Code Online (Sandbox Code Playgroud)
从这个例子中,你看到你需要某种方式来声明"我想继承这些构造函数"或"我想继承除了这些构造函数之外的所有构造函数",然后你还必须指定一个默认的构造函数继承偏好,以防万一有人在超类中添加一个新的构造函数...或者如果你想"继承"它们,你可能只需要重复超类中的构造函数,这可能是更明显的方法.
因为构造函数是一个实现细节 - 它们不是接口/超类的用户实际上可以调用的东西.当他们得到一个实例时,它已经被构建了; 反之亦然,在你构造一个对象时,根据定义,它没有当前分配给它的变量.
想想强制所有子类具有继承的构造函数意味着什么.我认为将变量直接传递给类比使用"神奇地"拥有一个具有一定数量参数的构造函数更为明确,因为它是父类.