2016-01-23 3 views
1

Я работаю над проектом, и найти себя не хватаю в объектно-ориентированном знании:Работа с производной собственностью внутри базового классом

Я хочу использовать метод базового класса, который содержит общий код для всех производных классов. Дело в том, что свойства, над которыми он должен работать, имеют различный тип в каждом производном классе, и поэтому он не «видит» их внутри базового класса. Например:

Public Interface IBase 
    Function CommonMethod() As Integer 
End Interface 

Public MustInherit Class BaseProperties 
    Public Property prop1 As String 
    Public Property prop2 As String 
End Class 

Public Class ActualProperties1 : Inherits BaseProperties 
    Public Property prop3 As String 
    Public Property prop4 As String 
End Class 

Public MustInherit Class BaseClass : Implements IBase 
    'placeholder for the actual PropertyClass class defined in each derived class 
    Public Overridable Property PropertyClass As Object 
    Public Function CommonMethod() As Integer Implements IBase.CommonMethod 
     Dim Varis as String = "" 
     'This correctly shows the derived class name 
     MsgBox(Me.GetType.Name) 
     'This throws an exception, as it is referencing the base class object which is nothing 
     MsgBox(Me.PropertyClass.GetType.Name) 
     'This is closer to what I actually want to do. 
     For Each prop As ComponentModel.PropertyDescriptor In ComponenModel.TypeDescriptor.GetProperties(Me.PropertyClass) 
      If prop.PropertyType.ToString = "System.String" Then 
       Varis += prop.GetValue() 
       prop.SetValue(Me.PropertyClass, "") 
      End If 
     Next 
     'Do something with Varis 
    End Function 
End Class 

Public Class DerivedClass : Inherits BaseClass 
    Public Property PropertyClass As ActualProperties1 
    Public Sub New() 
     PropertyClass = New ActualProperties1 
    End Sub 
End Class 

Public Class Form1 
    Dim cli As New DerivedClass 
    Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click 
     cli.prop1 = "test" 
     cli.prop4 = "test" 
     cli.CommonMethod() 
    End Sub 
End Class 

И есть несколько других классов, которые наследуют от BaseClass, и имеют свой собственный набор свойств, которые увеличивают BaseProperties, которые не являются общими для других, но CommonMethod() операция будет для всех классов.

В основном я хочу, чтобы избежать:

  • дублирования кода, не писать один и тот же код в каждом производном классе
  • Вызов метода базового с фактической собственности в качестве параметра, как этот CommonMethod (PropertyClass), если вам ребята говорят, что нет другого способа сделать это ... просто не так ли?

Я огляделся и, кажется, это невозможно, не делая еще одного класса, но я не уверен, так как ответы были на C#, так что есть шанс, что это дубликат.

Спасибо за ваше время!

+2

Это не то, как работает наследование. Базовый класс не должен знать о различных свойствах производных классов. – OneFineDay

+0

Базовый класс будет включать в себя код и свойства, которые используют все производные. * Но * если метод базового класса нуждается в чем-то из производного класса, почти по определению этот метод принадлежит другому классу. Эта декларация 'As Object 'будет меня бигать. Кроме того, вместо интерфейса Inheritance * и * Interfaces, посмотрите, не можете ли вы получить то же самое в более простой форме с помощью MustOveride – Plutonix

+0

То, что вы просите, выполняется все время в C#. В C# объект «T» используется в базовом классе для определения обобщенного типа, тогда «T» автоматически заменяется производным типом в каждом унаследованном классе. Для VB.NET см. Следующую публикацию: http://stackoverflow.com/questions/31864200/error-type-parameter-t-cannot-be-inferred – jdweng

ответ

0

Базовый класс не должен знать ничего о своих подклассах. То, что вы можете сделать, - это определить общую функцию в базовом классе и пометить ее MustOverride, которая заставит подклассы реализовать ее. Каждая реализация подкласса знает о своей собственной структуре и может вычислить производное свойство по мере необходимости. Вы можете сделать это для свойств, функций и подписей.

Смотрите в этом примере я просто бросил вместе:

Module Module1 

    Sub Main() 
     Dim Thing1 As BaseClass = New DerivedClass1 With {.NumberOfCows = 10} 

     Dim Thing2 As BaseClass = New DerivedClass2 With {.NumberOfGoats = 5, .NumberOfChickens = 20} 

     Console.WriteLine(Thing1.CalculateNumberOfAnimals()) 'Prints 10 
     Console.WriteLine(Thing2.CalculateNumberOfAnimals()) 'Prints 25 
    End Sub 

    Public MustInherit Class BaseClass 
     Public MustOverride Function CalculateNumberOfAnimals() As Integer 
    End Class 

    Public Class DerivedClass1 
     Inherits BaseClass 

     Public Property NumberOfCows As Integer 

     Public Overrides Function CalculateNumberOfAnimals() As Integer 
      Return NumberOfCows 
     End Function 
    End Class 

    Public Class DerivedClass2 
     Inherits BaseClass 

     Public Property NumberOfChickens As Integer 
     Public Property NumberOfGoats As Integer 

     Public Overrides Function CalculateNumberOfAnimals() As Integer 
      Return NumberOfChickens + NumberOfGoats 
     End Function 
    End Class 

End Module 
+0

Обновленный пример, чтобы сделать более понятным, что код действительно протекает через «BaseClass». –

Смежные вопросы