在VBA中实现多个接口的接口

问题描述 投票:0回答:2

我想创建一个实现多个接口的接口,然后创建一个实现该接口的类。例如:

有效模块:

Public Sub Fly()
End Sub

Public Function GetAltitude() As Long
End Function

ISwimmable模块:

Public Sub Swim()
End Sub

Public Function GetDepth() As Long
End Function

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

这全部编译正常。但是,如果我声明了IFlySwim类型的Object,则VBA中的预测性文本会给我:

IFlyable_Fly, IFlyable_GetAltitude, ISwimmable_Swim

并且试图创建实现IFlySwimmable的类是行不通的。

鸭类:

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

按下编译按钮会给我错误:“编译错误:对象模块需要为接口“ IFlySwim”实现“ IFlyable_Fly”。

因此,这使我相信Implement在另一个接口中创建一个接口是行不通的。至少,从VBA的角度来看,这没有任何意义。这是可以理解的,因为我实际上并未在IFlyable中提供ISwimmableIFlySwim的实现。我真正想做的是将IFlyableISwimmable的实现推迟到同时实现两者的类中进行。

现在,如果我的Duck类是:

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

然后,当我使用它时,预测性下拉菜单会给我:

Duck usage

我可以将Duck强制转换为IFlyableISwimmable以这样使用:

Duck usage 2

但是如果我想创建一个接受Flyable / Swimable的Function或Sub怎么办?我是否需要创建一个完全独立的接口IFlySwim,其中包含IFlyableISwimmable中的所有子功能,然后将我的Duck类修改为仅从IFlySwim中实现?

vba class interface implements multiple
2个回答
0
投票

不幸的是,这就是通过组合继承的方式。但是,您应该认识到Duck类将接口与函数实现的具体实现绑定在一起。您需要使用第二个间接级别

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

由此,您可以看到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

可能对您有帮助或对您没有帮助。


0
投票

接口方法/属性(即以下划线为前缀的方法/属性)不应公开。必须实现它们以实现派生类中接口的约定,但应将它们标记为私有。完成后,您可以使用诸如FlyGetAltitude的方法名称公开公共成员(请参见下文):

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

并且您的测试代码将变为以下内容:(见下文)

Sub InterfaceTest()

    Dim ducky As New Duck

    ducky.Fly
    Debug.Print ducky.GetAltitude()

    ducky.Swim
    Debug.Print ducky.GetDepth()

End Sub

但是如果我想创建一个接受Flyable / Swimable的Function或Sub怎么办?我是否需要创建一个完全独立的接口IFlySwim,其中包含IFlyable和ISwimmable的所有Sub / Function,然后将Duck类修改为仅从IFlySwim实现?

简短回答:是的。

为什么?

因为,VBA / VB6不完全支持继承。要执行您的要求,您将创建一个继承自ISwimmableIFlyable的第三个类,然后在其他类中实现该类。

使用像C#这样的完全面向对象的语言,您可以执行以下操作:(请参见下文)

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 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();

    }
}

产品:

Sea Duck:
Flying with wings!
50
Swimming!
100
Riding waves!


Mallard Duck:
Flying with wings!
100
Swimming!
10
Headed for land!
© www.soinside.com 2019 - 2024. All rights reserved.