gpt4 book ai didi

类 java 继承的 VBA 组合

转载 作者:行者123 更新时间:2023-12-04 02:53:53 24 4
gpt4 key购买 nike

在这个问题上稍微扩展一下 VBA inheritance pattern

我正在用 VBA 重现一个基本的继承模式,但我想了解是否有更有效、更简洁的方法来实现这一目标。

考虑这个小测试用例。

IAnimal.cls

'declaration
Public Sub eat()
End Sub

Public Sub breathe()
End Sub

Animal.cls:父类(super class)

Implements IAnimal

' method implementation
Private Sub IAnimal_eat()
Debug.Print "I'm eating something..."
End Sub

Private Sub IAnimal_breathe()
Debug.Print "I'm brething..."
End Sub

Cat.cls : Animal 的一个子类

Private super As IAnimal

Implements IAnimal

Private Sub Class_Initialize()
Set super = New Animal
End Sub


'#------------------------------------------------
' methods called when object is accessed as an IAnimal implementor.
' I HAVE TO re-implement all of them also here in the subclass (in java I don't need to. It's sufficient to implement them in the superclass)
Private Sub IAnimal_eat()
Me.eat
End Sub

Private Sub IAnimal_breathe()
Me.breathe
End Sub


'#--------------------------------------------------
' subclass-only methods
' To access those methods I MUST DECLARE the object as Cat (Dim tom as Cat)
Public Sub meow()
Debug.Print "meow..."
End Sub


'#------------------------------------------------
' superclass methods
' Since I need to declare the cat object as a Cat (see above)
' I'm FORCED TO explicitly re-implement all of the superclass methods,
' even those that I don't need to override
' otherwise I can't access them

'@Override
Public Sub eat()
Debug.print "I'm eating a fish!"
End Sub

'I'm forced to re-implement also this method, in order to use it directly on a *Cat* object
'@Unnecessary-Override
Public Sub breathe()
super.breathe
End Sub

测试.bas

Sub Main()

Dim snowball As IAnimal
Set snowball = New Cat

Dim tom As Cat
Set tom = New Cat

snowball.meow 'ERROR Method or data member not found <---- cannot access the Cat-only method "meow"
tom.meow '<--- prints "meow"

' creates a Dog, another subclass of Animal
Dim pluto As Dog
Set pluto = New Dog

'create a collection for all my animals
Dim myPets As Collection
Set myPets = New Collection

myPets.Add tom
myPets.Add pluto

Call feed(myPets) '<---- prints
'I 'm eating a fish
'meow...
'I 'm eating a bone
'woof...

End Sub

' a routine for showing how to manage an heterogeneous collection of animals
Sub feed(animals As Collection)

For Each a In animals

a.eat

If TypeOf a Is Cat Then
a.meow
End If

If TypeOf a Is Dog Then
a.woof
End If

Next

End Sub

通过这样做,我可以:

  • 对 Cat 和 Dog 对象调用 eat() 方法并具有特定的重写行为
  • 调用仅限子类的方法(如meow())
  • 将一个异类动物集合传递给一个feed子例程,它可以“安全地”调用Animal父类(super class)的方法并触发基于Animal子类的特定代码<

这似乎可行但很麻烦:假设您需要实现许多 Animal 子类(Dog、Bird、Armadillo、Platypus、Demogorgon 等)。上面的模式迫使你:

  1. 在所有子类上重新实现 IAnimal 接口(interface)的所有方法
  2. (再次)重新实现所有方法,以从子类中公开它们,即使不需要重写。如果您还想访问仅限子类的方法,这是特别需要的。

所以问题是:是否有更高效/简洁的方法来实现这个示例(并限制每个子类的代码重写)?

最佳答案

tom 一开始就不应该声明为 As Catfeed 过程是多余的:

Sub Main()    
Dim tom As IAnimal
Set tom = New Cat
tom.eat
End Sub

现在,在 Cat 类中,这些成员不需要存在:

'Superclass methods --- I have to explicitly override all methods :(
Public Sub eat()
super.eat
Debug.print "...a fish!"
End Sub

在 SOLID/OOP 中,您针对接口(interface)而不是具体类型进行编码 - 这就是为什么 tomIAnimal 而不是 Cat .通过它的 IAnimal 接口(interface)访问,Cat.eat 是完全多余的,并且暗示 Cat 做一些 IAnimal 不这样做,这违反了 SOLID 原则:突然间它变得相关,一个 IAnimal 是一个 Cat,它不应该是,因为多态性允许 IAnimal 是任何东西,Liskov 替换原则(LSP - “SOLID”的“L”)表示任何与 IAnimal 一起工作的代码都应该能够无论给定该接口(interface)的实现方式如何,都能以相同的方式工作。

遵守这些原则意味着任何 IAnimal 实现都不应在其默认接口(interface)上具有 IAnimal 成员的副本(例如 Cat.eat, vs IAnimal.eat),这完全消除了你的第 2 点:

  1. re-implements (again) all the methods, to expose them from the subclass, even when override is not necessary.

至于第 1 点......

  1. re-implement all the methods of the IAnimal interface

这是编译器的要求,而不是 VBA 的怪癖:无论是在 Java、C# 还是 VBA 中,你都不能说“我正在实现一个接口(interface)”……而不实现它的成员。当然,Java 和 C# 允许类继承,因此您的基类可以说“我正在实现一个接口(interface)”,实现所有成员,派生类会很乐意继承它们 - 但是,这就是继承,不再是组合

关于类 java 继承的 VBA 组合,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53873314/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com