为什么构造函数不继承?

时间:2012-02-20 15:13:59

标签: .net vb.net inheritance

作为后续问题,请Base Class Only Methods

父方法由其后代继承。

为什么构造函数(例如New())不是?  这对我来说似乎打破了继承。

是否有某个属性将其标记为特殊? (如果是这样的话是什么?)

可以这样解释发生了什么。

5 个答案:

答案 0 :(得分:4)

我怀疑真正的原因是双重的:

首先, no 静态(Shared)成员在VB#(或C#)中继承。虽然这与大多数OO语言的做法一致,但它不是必要的设计。可以想象,它可以以不同的方式实施。

其次,限制可以构造子对象的构造函数集通常是有意义的。特别是,由于子类通常具有需要初始化的其他成员,因此调用父类构造函数会使子进程处于未初始化状态。想象一下构造函数可以继承并告诉我以下代码应该做什么:

Class Base
    Public Sub New()
    End Sub
End Class

Class Derived : Inherits Base
    Public Property X() As Integer

    Public Sub New(ByVal value As Integer)
        X = value
    End Sub
End Class

' …

Dim foo As New Derived()
Console.WriteLine(foo.X) ' = ???

鉴于此,禁止构造函数的继承是很有意义的。

答案 1 :(得分:2)

继承(或者,确切地说,子类型关系)保证如果ST的子类型,则可以使用{{1}类型的对象每当需要S类型的对象时。

构造函数永远不能在对象上执行 - 它们被执行到创建对象。它们很特别:

T

换句话说,构造函数可以被视为静态(Visual Basic中的myS.SomeMethodOfT() ' works myS.New() ' doesn't work -- constructors are special. )方法返回特定类型的对象(并且某些语言实际上以这种方式实现):

Shared

答案 2 :(得分:1)

在构造函数中,您应该只构造该类的元素,而不是它的基类。通过调用基类的构造函数,将构造这些元素。

答案 3 :(得分:0)

除了已经给出的答案之外,还可以看一下对象创建的语义。

如果B类继承自A类,那么B类的所有对象都有两个组成部分:A的部分(继承)和B的部分(可能覆盖部分的部分) A)。

所以你可以把一个对象想象成所有祖先类的部分之和(加上它自己类的部分)。

现在考虑创建对象:如果创建了B类的对象,则不仅必须创建B部分,还要创建A部分。换句话说,如果调用B的构造函数,也必须调用A的构造函数(即使你没有在C#中显式调用base(),这也是总是的情况。 VB中的MyBase.New()

如果B从A继承其构造函数,那么它可以覆盖这样的构造函数。这可能导致A没有构造自己的部分的构造函数(因为所有构造函数都被覆盖),这使得A部分的对象创建成为不可能。

不继承构造函数不会破坏继承,它使它成为可能!

答案 4 :(得分:0)

为什么构造函数不能被继承的各种参数都是错误的。 pascal和c都是真正面向对象的语言,它们允许继承的构造函数。

上面引用的例子......

Class Base
    Public Sub New()
    End Sub
End Class

Class Derived : Inherits Base
    Public Property X() As Integer
    Public Sub New(ByVal value As Integer)
        X = value
    End Sub
End Class

'...     Dim foo As New Derived()

Console.WriteLine(foo.X)'= ???

答案是...... foo.x未初始化。但是使用未初始化的变量并不是语言的错误......这是程序员的错。

考虑另一个例子......

Class Base
    Public Property X As Integer
    Public Sub New(ByVal value As Integer)
        X = value
    End Sub
End Class

Class Derived : Inherits Base
End Class

'这有效......     Dim o as Base = New Base(5) '这不是。它可以用于pascal或c ......但不能用于vb(或者可能是c#)

Dim o as Derived = New Derived(5)

重点是继承的类不应该重写构造函数,除非它正在更改它的签名。现实情况是,这是微软拿走有价值工具的一个例子,因为太多的程序员无法正确使用该工具。