gpt4 book ai didi

oop - 我们可以同时使用接口(interface)和事件吗?

转载 作者:行者123 更新时间:2023-12-03 10:35:15 24 4
gpt4 key购买 nike

我仍在尝试了解接口(interface)和事件如何在 VBA 中协同工作(如果有的话?)。我即将在 Microsoft Access 中构建一个大型应用程序,我希望使其尽可能灵活和可扩展。为此,我想使用 MVC , Interfaces ( 2 ) ( 3 ) , Custom Collection Classes , Raising Events Using Custom Collection Classes , 寻找更好的方法 centralizemanage由窗体上的控件触发的事件,以及一些额外的 VBA design patterns .

我预计这个项目会变得非常棘手,所以我想尝试了解在 VBA 中同时使用接口(interface)和事件的限制和好处,因为它们是(我认为)在 VBA 中真正实现松散耦合的两种主要方式。

首先,有 this question关于尝试在 VBA 中同时使用接口(interface)和事件时引发的错误。答案是“显然不允许事件通过接口(interface)类传递到具体类,就像你想使用'Implements'一样。”

然后我在 answer on another forum 中找到了这条语句:“在 VBA6 中,我们只能引发在类的默认接口(interface)中声明的事件 - 我们不能引发在已实现接口(interface)中声明的事件。”

由于我仍在摸索界面和事件(VBA 是我真正有机会在现实世界中尝试 OOP 的第一种语言,我知道不寒而栗),我无法完全在脑海中解决所有问题这意味着在 VBA 中一起使用事件和接口(interface)。听起来你可以同时使用它们,但听起来你不能。 (例如,我不确定“类的默认接口(interface)”与“实现的接口(interface)”是什么意思。)

有人可以给我一些基本示例,说明在 VBA 中一起使用接口(interface)和事件的真正好处和限制吗?

最佳答案

严格来说,接口(interface)仅在 OOP 术语中是对象向外部世界(即它的调用者/“客户”)公开的内容。

所以你可以在类模块中定义一个接口(interface),比如ISomething :

Option Explicit
Public Sub DoSomething()
End Sub

在另一个类模块中,比如说 Class1 , 你可以实现 ISomething界面:
Option Explicit
Implements ISomething

Private Sub ISomething_DoSomething()
'the actual implementation
End Sub

当你这样做时,请注意 Class1不暴露任何东西; Access 其 DoSomething的唯一方法方法是通过 ISomething接口(interface),所以调用代码如下所示:
Dim something As ISomething
Set something = New Class1
something.DoSomething

所以 ISomething这里是接口(interface),实际运行的代码是在 Class1的body中实现的.这是 OOP 的基本支柱之一:多态性 - 因为您很可能拥有 Class2实现 ISomething以完全不同的方式,但调用者根本不需要关心:实现在接口(interface)后面抽象——这是在 VBA 代码中看到的美丽而令人耳目一新的东西!

不过,有很多事情要记住:
  • 字段通常被视为实现细节:如果接口(interface)公开了公共(public)字段,实现类必须实现 Property GetProperty Let (或 Set ,取决于类型)。
  • 事件也被认为是实现细节。因此它们需要在 Implements 的类中实现。接口(interface),而不是接口(interface)本身。

  • 最后一点很烦人。给定 Class1看起来像这样:
    '@Folder StackOverflowDemo
    Public Foo As String
    Public Event BeforeDoSomething()
    Public Event AfterDoSomething()

    Public Sub DoSomething()
    End Sub

    实现类如下所示:
    '@Folder StackOverflowDemo
    Implements Class1

    Private Sub Class1_DoSomething()
    'method implementation
    End Sub

    Private Property Let Class1_Foo(ByVal RHS As String)
    'field setter implementation
    End Property

    Private Property Get Class1_Foo() As String
    'field getter implementation
    End Property

    如果更容易可视化,项目如下所示:

    Rubberduck Code Explorer

    所以 Class1可能会定义事件,但实现类无法实现它们 - 这是 VBA 中事件和接口(interface)的一件可悲的事情,它源于 the way events work in COM - 事件本身在它们自己的“事件提供者”接口(interface)中定义;所以“类接口(interface)”不能在 COM 中公开事件(据我所知),因此在 VBA 中。

    因此,必须在实现类上定义事件才能有意义:
    '@Folder StackOverflowDemo
    Implements Class1
    Public Event BeforeDoSomething()
    Public Event AfterDoSomething()

    Private foo As String

    Private Sub Class1_DoSomething()
    RaiseEvent BeforeDoSomething
    'do something
    RaiseEvent AfterDoSomething
    End Sub

    Private Property Let Class1_Foo(ByVal RHS As String)
    foo = RHS
    End Property

    Private Property Get Class1_Foo() As String
    Class1_Foo = foo
    End Property

    如果你想处理事件 Class2在运行实现 Class1 的代码时引发接口(interface),你需要一个模块级的 WithEvents Class2 类型的字段(实现),以及 Class1 类型的过程级对象变量(界面):
    '@Folder StackOverflowDemo
    Option Explicit
    Private WithEvents SomeClass2 As Class2 ' Class2 is a "concrete" implementation

    Public Sub Test(ByVal implementation As Class1) 'Class1 is the interface
    Set SomeClass2 = implementation ' will not work if the "real type" isn't Class2
    foo.DoSomething ' runs whichever implementation of the Class1 interface was supplied
    End Sub

    Private Sub SomeClass2_AfterDoSomething()
    'handle AfterDoSomething event of Class2 implementation
    End Sub

    Private Sub SomeClass2_BeforeDoSomething()
    'handle BeforeDoSomething event of Class2 implementation
    End Sub

    所以我们有 Class1作为接口(interface), Class2作为实现,和 Class3作为一些客户端代码:

    Rubberduck Code Explorer

    ...这可以说违背了多态性的目的,因为该类现在与特定的实现相结合 - 但是,这就是 VBA 事件所做的:它们是实现细节,固有地与特定的实现相结合......据我所知.

    关于oop - 我们可以同时使用接口(interface)和事件吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41023670/

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