2014-05-21 70 views
3

我正在使用Excel VBA(Excel 2010),並且在嘗試使用繼承時遇到了問題。基本上,我有一個接口MyInterface和一個實現類MyImplementation。在VBA代碼中,當我參考MyInterface類型的Dim時,我只能訪問在該接口上定義的成員 - ,這是預計的。當我參考MyImplementation類型的Dim時,我無法訪問它實現的接口上定義的成員 - 不是預期的如何避免向接口類下推?

爲什麼我不能直接調用實現類上的接口屬性直接

MyInterface的

Option Explicit 

Public Property Get Text() As String 
End Property 

MyImplementation

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 

主要問題是我如何避免向下投射?

注 - 上面的例子是故意設計的。我意識到它通常是直接指向實現類的不好的做法。

回答

5

當我引用Dim類型MyImplementation時,我無法訪問它實現的接口上定義的成員 - 不是預期的。

解決方案是改變你的期望。這就是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 
+0

*解決方法是改變你的期望* - 赫赫同意! WRT你的答案,我已經看到這個解決方案在線。對於MyImplementation的客戶端代碼來說,解決方案很好,但對於MyInterface的所有實現者來說都不是。如果我在我的界面和10個實現類中有10個屬性,那就是我必須寫的100個方法!從長遠來看,這似乎相當難以維持。無論如何,你打擊了腦袋:我需要改變我的期望!感謝您的答覆 - 接受! – Muel

+0

快速提問:你碰巧知道VB.NET是否需要相同的技術?還是按我最初的期望工作? – Muel

+0

沒有VB.NET沒有這個限制。 – Joe

0

簡單的聲明實現方法爲公共的,而不是私人會做:

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 

就是這樣。