Почему конструктор не унаследован? - PullRequest
5 голосов
/ 20 февраля 2012

В качестве дополнительного вопроса к Методы только для базового класса

Родительские методы наследуются их потомками.

Почему тогда Конструкторы (например, New ()) нет? Который, кажется, нарушает наследство.

Есть ли где-нибудь атрибут, который помечает его как особый? (Если так, что это?)

Может ли кто-нибудь объяснить, что происходит?

Ответы [ 5 ]

4 голосов
/ 20 февраля 2012

Я подозреваю, что настоящая причина двояка:

Прежде всего, нет статических (Shared) членов наследуются в VB # (или 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) ' = ???

Учитывая это, имеет смысл запретить наследование конструкторов.

2 голосов
/ 20 февраля 2012

Наследование (или, если быть точным, отношение подтипа ) гарантирует, что если S является подтипом T, вы можете использовать объект типа S всякий раз, когда объект типа T требуется.

Конструкторы никогда не могут быть выполнены на объекте - они выполняются для создания объекта. Они особенные в этом смысле:

myS.SomeMethodOfT()    ' works
myS.New()              ' doesn't work -- constructors are special.

Другими словами, конструктор можно рассматривать как статический (Shared в Visual Basic) метод, возвращающий объект определенного типа (а некоторые языки фактически реализуют его таким образом):

Dim myS = New S()      ' can be seen as syntactic sugar for 
                       ' something like myS = S.CreateNew()
1 голос
/ 20 февраля 2012

В конструкторе вы должны создавать только элементы для этого класса, а не его базовый класс. Вызовом конструктора базового класса будут созданы эти элементы.

0 голосов
/ 10 апреля 2013

Различные аргументы, почему конструкторы не могут быть унаследованы, ошибочны.И 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

'Это работает ... Dimo как База = Новая База (5) 'Это не так.Это будет работать в Паскале или C ..., но не в VB (или, предположительно, C #)должен переопределить конструктор, если он не меняет свою подпись.Реальность такова, что это пример того, как Microsoft забирает ценный инструмент, потому что слишком много программистов не способны правильно использовать этот инструмент.

0 голосов
/ 20 февраля 2012

В дополнение к уже приведенным ответам также интересно взглянуть на семантику создания объекта.

Если класс B наследуется от класса A, то все объекты классаB имеет два компонента: части A (которые наследуются) и части B (которые могут перекрывать некоторые части A).

Таким образом, вы можете думать об объекте как о сумме частейвсе классы-предки (плюс части своего собственного класса).

Теперь подумайте о создании объекта: если создается объект для класса B, должна быть создана не только часть B, но и часть A.Другими словами, если вызывается конструктор для B, должен также вызываться конструктор для A (это всегда случай, даже если вы явно не вызываете base() в C # или MyBase.New()в VB).

Если B наследует свои конструкторы от A, то он может переопределить такой конструктор.Это может привести к ситуации, когда у A не останется никакого конструктора для построения своей собственной части (поскольку все конструкторы переопределяются), что делает невозможным создание объектов из частей A.

Отсутствие наследования конструкторов не нарушает наследование, оно делаетэто возможно!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...