Вкратце: композиция Favor over Inheritance
Интерфейсы - это просто общий набор определений членов, которые вы хотите, чтобы один или несколько классов поддерживали. Ключ заключается в том, что вы должны явно предоставлять функциональность при реализации интерфейса.
Вы можете достичь аналогичных результатов, используя наследование, так как два подкласса могут наследовать полнофункциональные члены из базы. Но недостатком наследования является то, что ваши подклассы в конечном итоге имеют жесткую зависимость от базового класса.
Рассмотрим следующие классы:
Public Class Car
Publc Sub OpenDoor(ByVal key As MyKey)
Console.WriteLine("Access granted to car.")
End Sub
End Class
Public Class House
Public Sub OpenDoor(ByVal key as MyKey)
Console.WriteLine("Access granted to house.")
End Sub
End Class
Вы могли бы сказать, что эти два класса несколько связаны, потому что у них обоих есть метод OpenDoor (). Может возникнуть соблазн даже создать базовый класс для извлечения общей функциональности.
Public Class OpenableProperty
Public Sub OpenDoor(ByVal key As MyKey)
Console.WriteLine("Access granted to property.")
End Sub
End Class
Public Class Car
Inherits OpenableProperty
End Class
Public Class House
Inherits OpenableProperty
End Class
Затем вы можете использовать эту абстракцию следующим образом:
Public Class SecurityService
Public Sub InspectProperty(ByVal item As OpenableProperty)
Dim key As New MyKey()
Console.WriteLine("Inspecting property...")
item.OpenDoor(key)
End Sub
End Class
Однако отношение дома к автомобилю, основанное исключительно на том факте, что вы можете получить к ним доступ с помощью ключа, является довольно слабой абстракцией. Черт, даже банку с фасолью можно открыть!
Но есть и другие моменты, где также может возникнуть связь. Например, как автомобиль, так и дом могут иметь кондиционер:
Public Class Car
Inherits OpenableProperty
Public Sub TurnOnAirConditioning()
Console.WriteLine("Cool breezes flowing in car!")
End Sub
End Class
Public Class House
Inherits OpenableProperty
Public Sub TurnOnAirConditioning()
Console.WriteLine("Cool breezes flowing in house!")
End Sub
End Class
Должен ли TurnOnAirConditioning () быть извлечен и в базовый класс? Какое это имеет отношение к тому, чтобы быть OpenableProperty? Может ли класс JewelrySafe наследоваться от OpenableProperty без AC? Лучший ответ в этой ситуации - извлечь интерфейсы и использовать их для создания функциональности в наших классах, а не наследовать:
Public Interface IOpenable
Sub OpenDoor(ByVal key As MyKey)
End Interface
Public Interface ICoolable
Sub TurnOnAirConditioning()
End Interface
Public Class Car
Implements IOpenable, ICoolable
Public Sub OpenDoor(ByVal key as MyKey) Implements IOpenable.OpenDoor()
Console.WriteLine("Access granted to car.")
End Sub
Public Sub TurnOnAirConditioning() Implements ICoolable.TurnOnAirConditioning()
Console.WriteLine("Cool breezes flowing in car!")
End Sub
End Class
Public Class House
Implements IOpenable, ICoolable
Public Sub OpenDoor(ByVal key as MyKey) Implements IOpenable.OpenDoor()
Console.WriteLine("Access granted to house.")
End Sub
Public Sub TurnOnAirConditioning() Implements ICoolable.TurnOnAirConditioning()
Console.WriteLine("Cool breezes flowing in house!")
End Sub
End Class
Public Class JewelrySafe
Implements IOpenable
Public Sub OpenDoor(ByVal key as MyKey) Implements IOpenable.OpenDoor()
Console.WriteLine("Access granted to jewelry safe.")
End Sub
End Class
Тогда ваши абстракции могут быть использованы как таковые:
Public Class SecurityService
Public Sub InspectProperty(ByVal item As IOpenable)
Dim key As New MyKey()
Console.WriteLine("Inspecting property...")
item.OpenDoor(key)
End Sub
End Class
Public Class ThermostatService
Public Sub TestAirConditioning(ByVal item as ICoolable)
Console.WriteLine("Testing Air Conditioning...")
item.TurnOnAirConditioning()
End Sub
End Class
Служба SecurityService может затем использоваться для проверки Car, House и JewelrySafe, тогда как служба ThermostatService может использоваться только для проверки AC машины и House.
Sub Main()
Dim securityService As New SecurityService()
Dim thermostatService As New ThermostatService()
Dim house As New House()
Dim car As New Car()
Dim jewelrySafe As New JewelrySafe()
With securityService
.InspectProperty(house)
.InspectProperty(car)
.InspectProperty(jewelrySafe)
End With
With thermostatService
.TestAirConditioning(house)
.TestAirConditioning(car)
End With
End Sub
Что должно дать следующие результаты:
Inspecting property...
Access granted to house.
Inspecting property...
Access granted to car.
Inspecting property...
Access granted to jewelry safe.
Testing Air Conditioning...
Cool breezes flowing in house!
Testing Air Conditioning...
Cool breezes flowing in car!