2

我只是在学习 Spring4D,我有一个问题。如果类只实现一个接口,那么一切都清楚:

    IWeapon = interface
        ['{E679EDA6-5D43-44AD-8F96-3B5BD43A147B}']
        procedure Attack;
    end;

    TSword = class(TInterfacedObject, IWeapon)
    public
        procedure Attack;
    end;

    GlobalContainer.RegisterType<TSword>.Implements<IWeapon>('sword');
    sword := ServiceLocator.GetService<IWeapon>('sword');

我现在真的很开心,我有剑,我不需要释放它。

但是如果类实现了两个或更多接口:

    IWeapon = interface
        ['{E679EDA6-5D43-44AD-8F96-3B5BD43A147B}']
        procedure Attack;
    end;

    IShield = interface
        ['{B2B2F443-85FE-489C-BAF4-538BB5B377B3}']
        function Block: Integer;
    end;

    TSpikedShield = class(TInterfacedObject, IWeapon, IShield)
    public
        function Block: Integer;
        procedure Attack;
    end;

    GlobalContainer.RegisterType<TSpikedShield>.Implements<IWeapon>.Implements<IShield>;

我可以向 ServiceLocator 询问 TSpikedShield 的实例,但我需要选择一个 IWeapon 或 IShield。但我想以两种方式使用它(或者我不应该想要?),比如:

spikedShield.Attack;
spikedShield.Block;

因此,如果我很好理解,我必须直接创建 TSpikedShiled 的实例(我的意思是没有接口)。

function MakeSpikedShield: TSpickedShield;
begin
    result := TSpickedShield.Create;
end;

有什么方法可以使用这个类,但自动免费?

(如果接口可以实现多接口,但在delphi中不允许,则不会有问题)

编辑:也许有人这样想?

ISpikedSield = interface
    function AsWeapon: IWeapon;
    function AsShield: IShield;
end;
TSpikedShield = class(TInterfacedObject, ISpikedShield)
4

1 回答 1

6

如果接口可以实现多接口就没有问题,但在Delphi中是不允许的

这就是问题的确切原因。

我只会创建一个ISpikedShield具有 and 方法的接口,IWeaponIShield确保实现的每个类ISpikedShield也显式实现IWeaponand IShield(这是编译器在 C# 中基本上为您所做的,例如,接口可以从多个其他接口继承)。

然后,您不能将 an 分配ISpikedShieldIWeaponandIShield但使用 as 运算符将起作用,因为后面的类实现了它们。

但是,我不确定您的架构中是否存在误解,因为如果您进一步思考,将不会有一个类具有ISpikedShieldas 依赖项而是具有IWeaponand/or IShield。然后,一些游戏代码会检查您的IShield支持ICanAttack是否除了可以使用IWeapon.

于 2016-06-24T13:47:42.427 回答