首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >多显式接口实现

多显式接口实现
EN

Stack Overflow用户
提问于 2011-06-19 21:43:47
回答 7查看 1.7K关注 0票数 7

我有以下基本接口

代码语言:javascript
复制
public interface IBaseAction
{
   bool CanAct(...)
}

两个继承接口说

代码语言:javascript
复制
public interface IAction1 : IBaseAction{}

代码语言:javascript
复制
public interface IAction2 : IBaseAction{}

我的问题是,我有一个实现两者的类,并且我希望以不同的方式实现CanAct。

代码语言:javascript
复制
public class ComplexAction : IAction1, IAction2
{
   bool IAction1.CanAct(...){} //doesn't compile as CanAct is not a member of IAction1!!
}

ComplexAction c=new ComplexAction();
var a1 = (IAction1)c;
var a2 = (IAction2)c;
a1.CanSave(); //THESE TWO CALLS SHOULD BE IMPLEMENTED DIFFERENTLY
a2.CanSave();

有一个相当干净的方法来做这件事吗?

(而且,我的接口具有语义意义,并且至少还有三个函数,所以不可能抛出整个层次结构,但是如果只有这个解决方案,我愿意将bool CanAct复制到每个继承接口(其中有4-6个)。

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2011-06-19 21:46:11

如果有人打电话给((IBaseAction)a1).CanSave(),那么CLR应该做什么?IBaseAction.CanSave()可能只有一个实现。所以我认为你不能在概念上做到这一点。

这是一个名为钻石问题的多重继承的基本问题。底线是:如果你点击它,你的类型层次结构设计肯定是错误的。例如,在这种特殊情况下,您最好使用角色类模型 (也称为角色模式)。

票数 5
EN

Stack Overflow用户

发布于 2011-06-19 21:51:56

你不能照你说的做。想象一下,如果客户机请求IBaseAction接口,会发生什么情况。应该归还哪一个?

在我看来,每个动作都应该由不同的对象来实现。

票数 5
EN

Stack Overflow用户

发布于 2011-06-19 22:13:40

您正在尝试使用接口实现钻石继承。首先,不允许实现多个类的全部原因是为了避免钻石继承。

如果要将两个接口合并为一个ComplexAction,可以执行如下操作:

代码语言:javascript
复制
interface IAct
{
    bool CanAct();
}

class Act1 : IAct
{
    public bool CanAct()
    {
        return true;
    }
}

class Act2 : IAct
{
    public bool CanAct()
    {
        return false;
    }
}

class ComplexAction : IAct
{
    private Act1 action1;
    private Act2 action2;

    public ComplexAction(Act1 action1, Act2 action2)
    {
        this.action1 = action1;
        this.action2 = action2;
    }

    public bool CanAct()
    {
        return action1.CanAct() && action2.CanAct();
    }
}

ComplexAction是由不同的IAct组成的,如果您在接口名称中添加了一个数字,则很有可能您做错了什么。

如果您想要基于接口定义不同的行为,则该接口必须在其本身上定义它的方法。

代码语言:javascript
复制
interface IAct1
{
    bool CanAct();
}

interface IAct2
{
    bool CanAct();
}

class SometimesAct1SometimesAct2 : IAct, IAct1, IAct2
{
    bool IAct1.CanAct()
    {
        return false;
    }

    bool IAct2.CanAct()
    {
        return true;
    }

    public bool CanAct()
    {
        Console.WriteLine("Called on IAct or SometimesAct1SometimesAct2");
        return false;
    }
}

为了避免钻石继承的问题,您必须为定义特定方法的所有接口提供一个实现,这样就没有歧义。

票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6405284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档