Как наследовать абстрактный защищенный вложенный класс в производном классе - PullRequest
0 голосов
/ 01 сентября 2009

Я на самом деле еще не сделал этого, и, может быть, мне не нужно, но это имело смысл для меня. У меня есть базовый класс, скажем, BaseClass, где у меня есть несколько производных классов, скажем, Derived1, Derived2, Derived3. У меня есть несколько операций, которые применяются только к одной конкретной функции, а именно, создание PDF. Моя идея состояла в том, чтобы взять все эти методы (некоторые являются абстрагированными от базового класса) и подключить их во вложенный абстрактный класс в базовом классе, например:

Public MustInherit Class BaseClass
    Protected MustOverride Sub MethodA()
    Protected MustOverride Sub MethodB()

    ...stuff

    Protected MustInherit Class PDFOperations
        Protected MustOverride Sub Method1()
        Protected MustOverride Sub Method2()

        etc.

    End Class
End Class

Таким образом, когда я хочу найти что-то в своем классе, я могу абстрагировать свои операции PDF от всего остального, что сделает мой интерфейс более чистым. Есть ли способ сделать это так, что мои производные классы будут вынуждены переопределить вложенный класс и все его методы? Или это просто глупый способ сделать это?

1 Ответ

1 голос
/ 01 сентября 2009

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

Public MustInherit Class BaseClass
    Protected MustOverride Sub MethodA()
    Protected MustOverride Sub MethodB()

    ...stuff

    Protected MustInherit Class PDFOperations
        Protected MustOverride Sub Method1()
        Protected MustOverride Sub Method2()

        etc.

    End Class

    Protected MustOverride ReadOnly Property PDF
End Class

Простого создания вложенного класса абстрактным недостаточно, чтобы требовать, чтобы унаследованный класс действительно их реализовал (поскольку вы нигде не ссылаетесь на этот класс). Вложенные классы .NET похожи на вложенные static классы в Java тем, что у них нет ссылки на конкретный экземпляр содержащего класса, они просто сгруппированы, из-за отсутствия лучшего термина, по внешнему классу и имеют доступ для закрытых, защищенных и внутренних членов содержащего класса.

Предоставляя абстрактное свойство только для чтения, которое имеет тип абстрактного внутреннего класса, вы затем требуете, чтобы наследующий класс предоставлял НЕКОТОРЫЕ конкретные реализации этого и ломал ваши методы так, как вам нравится.

Редактировать

Несмотря на то, что абсолютно невозможно принудительно применить тот КАЖДЫЙ класс, который наследуется от BaseClass, обеспечивает отличную реализацию класса PDFOperations, это реализуется с практической точки зрения, поскольку любой класс, который наследует от PDFOperations, будет быть Protected вложенным классом класса, который наследуется от BaseClass. Это означает, что они не могут совместно использовать реализации.

Примеры

Public Class DerivedOne Inherits BaseClass
    Protected Overrides Sub MethodA() ...
    Protected Overrides Sub MethodB() ...

    Private pdfInstance as PDFOne

    Protected Class PDFOne Inherits PDFOperations
        Protected Overrides Sub Method1() ...
        Protected Overrides Sub Method2() ...

        Private instance as DerivedOne

        Public Sub New(ByVal instance as DerivedOne)
            Me.instance = instance
        End Sub
    End Class

    Protected Overrides ReadOnly Property PDF
        Get
            If pdfInstance is Nothing Then pdfInstance = new PDFOne(Me)

            return pdfInstance
        End Get
    End Property
End Class

Public Class DerivedTwo Inherits BaseClass
    Protected Overrides Sub MethodA() ...
    Protected Overrides Sub MethodB() ...

    Private pdfInstance as PDFTwo

    Protected Class PDFTwo Inherits PDFOperations
        Protected Overrides Sub Method1() ...
        Protected Overrides Sub Method2() ...

        Private instance as DerivedTwo

        Public Sub New(ByVal instance as DerivedTwo)
            Me.instance = instance
        End Sub
    End Class

    Protected Overrides ReadOnly Property PDF
        Get
            If pdfInstance is Nothing Then pdfInstance = new PDFTwo(Me)

            return pdfInstance
        End Get
    End Property
End Class

В PDFOne и PDFTwo существует переменная экземпляра с именем instance, которая представляет ссылку на содержащий объект, который наследуется от BaseClass

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