【问题标题】:How do I avoid down-casting to the interface class?如何避免向下转换为接口类?
【发布时间】:2014-07-09 10:48:59
【问题描述】:

我正在使用 Excel VBA (Excel 2010),但在尝试使用继承时遇到了问题。基本上,我有一个接口MyInterface 和一个实现类MyImplementation。在 VBA 代码中,当我引用 MyInterface 类型的 Dim 时,我只能访问在该接口上定义的成员 - 这是预期的。当我引用 MyImplementation 类型的 Dim 时,我无法访问在它实现的接口上定义的成员 - 不是预期的

为什么不能在实现类上直接调用接口属性?

我的界面

Option Explicit

Public Property Get Text() As String
End Property

我的实现

Option Explicit
Implements MyInterface

'The implementation of the interface method'
Private Property Get MyInterface_Text() As String
  MyInterface_Text = "Some Text"
End Property

Public Property Get MoreText() As String
  MoreText = "Yes, some more text!"
End Property

MainModule - 使用示例

Function Stuff()
  Dim impl As New MyImplementation
  Dim myInt As MyInterface: Set myInt = impl
  'The following line is fine - displays "Yes, some more text!"
  MsgBox impl.MoreText
  'This is also fine - displays "Some text"
  MsgBox DownCast(impl).Text
  'This is also fine - displays "Some text"
  MsgBox myInt.Text
  'This is *not* fine - why??
  MsgBox impl.Text
End Function

Function DownCast(ByRef interface As MyInterface) As MyInterface
  Set DownCast = interface
End Function

主要问题是如何避免向下转换?

注意 - 上面的示例是故意设计的。我意识到直接引用实现类通常是不好的做法。

【问题讨论】:

    标签: vba excel inheritance casting


    【解决方案1】:

    当我引用 MyImplementation 类型的 Dim 时,我无法访问在它实现的接口上定义的成员 - 这不是预期的。

    解决方案是改变您的期望。这就是 VBA 中的工作方式:VBA 类实现 COM 接口(例如 IUnknown)而不公开它们。

    如果你想从类中公开你的接口的成员,你必须明确地这样做:

    Option Explicit
    Implements MyInterface
    
    'The implementation of the interface method'
    Private Property Get MyInterface_Text() As String
        MyInterface_Text = "Some Text"
    End Property
    
    Public Property Get MoreText() As String
        MoreText = "Yes, some more text!"
    End Property
    
    Public Property Get Text() As String
        Text = MyInterface_Text 
    End Property
    

    【讨论】:

    • 解决办法就是改变你的期望。 - 呵呵同意了! WRT你的答案,我在网上看到了这个解决方案。对于MyImplementation 的客户端代码,解决方案很好,但对于MyInterface 的所有实现者来说,它不是。如果我的接口上有 10 个属性和 10 个实现类,那就是我必须编写的 100 个方法!从长远来看,这似乎是难以维持的。无论如何,你一针见血:我需要改变我的期望!感谢您的回答 - 已接受!
    • 快速提问:您是否知道 VB.NET 是否需要相同的技术?还是按照我最初的预期工作?
    • 没有VB.NET没有这个限制。
    【解决方案2】:

    只需将实现方法声明为 Public 而不是 Private 即可:

    Option Explicit
    ' Class MyImpl
    Implements MyInterface
    
    'The implementation of the interface method'
    'Notice the Public here instead of private'
    Public Property Get MyInterface_Text() As String
        MyInterface_Text = "Some Text"
    End Property
    

    唯一要记住的是,要调用实现中的方法,您需要使用更长的名称:

    Dim instance as MyImpl
     ' initialize your instance
    instance.MyInterface_Text 
    ' instead of instance.Text
    

    就是这样。

    【讨论】:

      猜你喜欢
      • 2011-11-24
      • 2022-07-31
      • 2014-08-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-01-18
      • 2020-12-05
      相关资源
      最近更新 更多