[英]Interface implementing multiple interfaces in VBA
I would like to create an Interface that implements multiple interfaces, and then make a class that implements that interface.我想创建一个实现多个接口的接口,然后制作一个实现该接口的 class。 For example:
例如:
IFlyable module: IFlyable 模块:
Public Sub Fly()
End Sub
Public Function GetAltitude() As Long
End Function
ISwimmable module: ISwimmable 模块:
Public Sub Swim()
End Sub
Public Function GetDepth() As Long
End Function
IFlySwim module: IFlySwim 模块:
Implements IFlyable
Implements ISwimmable
Public Sub IFlyable_Fly()
End Sub
Public Function IFlyable_GetAltitude() As Long
End Function
Public Sub ISwimmable_Swim()
End Sub
Public Function ISwimmable_GetDepth() As Long
End Function
This all compiles just fine.这一切都编译得很好。 But if I declare an Object of type IFlySwim, the predictive text in VBA gives me:
但是,如果我声明一个 IFlySwim 类型的 Object,VBA 中的预测文本会给我:
And trying to create a Class that implements IFlySwimmable just doesn't work.并且试图创建一个实现 IFlySwimmable 的 Class 是行不通的。
Class Duck: Class 鸭:
Implements IFlySwim
Public Sub IFlySwim_IFlyable_Fly()
Debug.Print "Flying with wings!"
End Sub
Public Function IFlySwim_IFlyable_GetAltitude() As Long
IFlySwim_IFlyable_GetAltitude = 30
End Function
Public Sub IFlySwim_ISwimmable_Swim()
Debug.Print "Swimming with feet!"
End Sub
Public Function IFlySwim_ISwimmable_GetDepth() As Long
IFlySwim_ISwimmable_GetDepth = 20
End Function
Pressing the compile button gives me the error: "Compile error: Object module needs to implement 'IFlyable_Fly' for interface 'IFlySwim'.按编译按钮给我错误:“编译错误:Object 模块需要为接口 'IFlySwim' 实现 'IFlyable_Fly'。
So this leads me to believe that Implement
ing an interface within another interface Doesn't Work.所以这让我相信在另一个接口中
Implement
一个接口是行不通的。 Or at least, it doesn't make sense from VBA's point of view.或者至少,从 VBA 的角度来看,它没有意义。 Which is understandable, because I'm not actually providing an implementation for
IFlyable
and ISwimmable
in IFlySwim
.这是可以理解的,因为我实际上并没有在
IFlySwim
中提供IFlyable
和ISwimmable
的实现。 What I really want to do is defer implementation for IFlyable
and ISwimmable
to a class that implements both of them.我真正想做的是将
IFlyable
和ISwimmable
的实现推迟到实现它们的 class 。
So now, if my Duck
class is:所以现在,如果我的
Duck
class 是:
Implements IFlyable
Implements ISwimmable
Public Sub IFlyable_Fly()
Debug.Print "Flying with wings!"
End Sub
Public Function IFlyable_GetAltitude() As Long
IFlyable_GetAltitude = 30
End Function
Public Sub ISwimmable_Swim()
Debug.Print "Swimming with feet!"
End Sub
Public Function ISwimmable_GetDepth() As Long
ISwimmable_GetDepth = 20
End Function
Then when I go to use it, the predictive dropdown gives me:然后当我 go 使用它时,预测下拉菜单给了我:
I could cast Duck
to either the IFlyable
or ISwimmable
to use as such:我可以将
Duck
转换为IFlyable
或ISwimmable
来使用:
But what if I wanted to create a Function or Sub that accepts a Flyable/Swimmable?但是,如果我想创建一个接受 Flyable/Swimmable 的 Function 或 Sub 怎么办? Do I have to create a completely separate interface called IFlySwim that contains all of the Sub/Functions from
IFlyable
and ISwimmable
, and then modify my Duck
class to only implement from the IFlySwim
?我是否必须创建一个名为 IFlySwim 的完全独立的接口,其中包含来自
IFlyable
和ISwimmable
的所有子/功能,然后修改我的Duck
class 以仅从IFlySwim
实现?
Unfortunately, that is how inheritance by composition works.不幸的是,这就是 inheritance 的工作原理。 However you should realise that your Duck class is tying the interface to the concrete implementation of the function implementations.
但是,您应该意识到您的 Duck class 将接口与 function 实现的具体实现联系起来。 You need to use a second level of indirection
您需要使用第二级间接
Implements IFlyable
Implements ISwimmable
Private Sub IFlyable_Fly()
Fly
End Sub
|Private Function IFlyable_GetAltitude() As Long
IFlyable_GetAltitude=GetAltitude
End Function
Private Sub ISwimmable_Swim()
Swim
End Sub
Private Function ISwimmable_GetDepth() As Long
ISwimmable=GetDepth
End Function
Public Sub Fly()
Debug.Print "Flying with wings!"
End Sub
Public Function GetAltitude() As Long
GetAltitude = 30
End Function
Public Sub Swim()
Debug.Print "Swimming with feet!"
End Sub
Public Function GetDepth() As Long
GetDepth = 20
End Function
From this you can see that GetAltitude and GetDepth could both refer to a property of VerticalPosition从这里你可以看到 GetAltitude 和 GetDepth 都可以引用 VerticalPosition 的属性
Private Function IFlyable_GetAltitude() As Long
IFlyable_GetAltitude=GetVerticalPosition
End Function
Private Function ISwimmable_GetDepth() As Long
ISwimmable_GetDepth=- GetVerticalPosition
End function
Which may or may not be helpful top you.这可能对您有帮助,也可能对您没有帮助。
Interface methods/properties (ie methods/properties prefixed with an underscore) should not be exposed as public.接口方法/属性(即以下划线为前缀的方法/属性)不应公开。 They must be implemented to fulfill the contract of the interface in the derived class, but they should be marked as private.
必须实现它们以履行派生 class 中的接口契约,但应将它们标记为私有。 Once you have done so, you can expose public members with method names like
Fly
or GetAltitude
(see below):完成此操作后,您可以使用
Fly
或GetAltitude
等方法名称公开公共成员(见下文):
Option Explicit
Implements ISwimmable
Implements IFlyable
'********************************************************
'Public Methods
'********************************************************
Public Function GetDepth() As Long
GetDepth = 10
End Function
Public Sub Swim()
Debug.Print "Swimming!"
End Sub
Public Function GetAltitude() As Long
GetAltitude = 50
End Function
Public Sub Fly()
Debug.Print "Flying with wings!"
End Sub
'********************************************************
'Private Methods
'********************************************************
Private Function ISwimmable_GetDepth() As Long
End Function
Private Sub ISwimmable_Swim()
End Sub
Private Function IFlyable_GetAltitude() As Long
End Function
Private Sub IFlyable_Fly()
End Sub
And your test code becomes the following: (see below)您的测试代码如下:(见下文)
Sub InterfaceTest()
Dim ducky As New Duck
ducky.Fly
Debug.Print ducky.GetAltitude()
ducky.Swim
Debug.Print ducky.GetDepth()
End Sub
But what if I wanted to create a Function or Sub that accepts a Flyable/Swimmable?
但是,如果我想创建一个接受 Flyable/Swimmable 的 Function 或 Sub 怎么办? Do I have to create a completely separate interface called IFlySwim that contains all of the Sub/Functions from IFlyable and ISwimmable, and then modify my Duck class to only implement from the IFlySwim?
我是否必须创建一个名为 IFlySwim 的完全独立的接口,其中包含来自 IFlyable 和 ISwimmable 的所有子/功能,然后修改我的 Duck class 以仅从 IFlySwim 实现?
Short answer: Yes.简短的回答:是的。
Why?为什么?
Because, VBA/VB6 does not support inheritance fully.因为,VBA/VB6 不完全支持 inheritance。 To do what you ask, you would have create a third class that inherits from
ISwimmable
and IFlyable
, and then implement that class in other classes.按照您的要求,您将创建第三个 class 继承自
ISwimmable
和IFlyable
,然后在其他类中实现该 class 。
In a fully OOP language like C#
, you could to the following: (see below)在像
C#
这样的完全 OOP 语言中,您可以执行以下操作:(见下文)
public interface IFlyable {
void Fly();
int GetAltitude();
}
public interface ISwimmable {
void Swim();
int GetDepth();
}
//Base Class
public abstract class BaseDuck: ISwimmable, IFlyable {
public BaseDuck(){}
public void Fly() {
Console.WriteLine("Flying with wings!");
}
public virtual int GetAltitude() {
return 50;
}
public void Swim() {
Console.WriteLine("Swimming!");
}
public virtual int GetDepth() {
return 10;
}
}
//Derived Class
public class SeaDuck: BaseDuck {
public SeaDuck(){}
public override int GetAltitude() {
return 50;
}
public override int GetDepth() {
return 100;
}
public void RideWaves() {
Console.WriteLine("Riding waves!");
}
}
//Derived Class
public class MallardDuck: BaseDuck {
public MallardDuck(){}
public override int GetAltitude() {
return 100;
}
public override int GetDepth() {
return 10;
}
public void HeadToLandForWinter() {
Console.WriteLine("Headed for land!");
}
}
Using the following to test: (see below)使用以下测试:(见下文)
using System;
public class Program
{
public static void Main()
{
SeaDuck seaDuck = new SeaDuck();
Console.WriteLine("Sea Duck:");
seaDuck.Fly();
Console.WriteLine(seaDuck.GetAltitude().ToString());
seaDuck.Swim();
Console.WriteLine(seaDuck.GetDepth().ToString());
seaDuck.RideWaves();
Console.WriteLine("\n");
Console.WriteLine("Mallard Duck:");
MallardDuck mallardDuck = new MallardDuck();
mallardDuck.Fly();
Console.WriteLine(mallardDuck.GetAltitude().ToString());
mallardDuck.Swim();
Console.WriteLine(mallardDuck.GetDepth().ToString());
mallardDuck.HeadToLandForWinter();
}
}
Produces:生产:
Sea Duck:
Flying with wings!
50
Swimming!
100
Riding waves!
Mallard Duck:
Flying with wings!
100
Swimming!
10
Headed for land!
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.