简体   繁体   English

接口继承

[英]Interface inheritance

I have an interface called IStrategy : 我有一个名为IStrategy的界面:

public interface IStrategy
{
}

I have another interface called IClickStrategy that inherits from IStrategy . 我有另一个名为IClickStrategy的接口,它继承自IStrategy It has a method called GetClicks() : 它有一个名为GetClicks()的方法:

public interface IClickStrategy : IStrategy
{
   void GetClicks(string[] args);
}

And a class that inherits from IClickStrategy and implements the GetClicks() method: 还有一个继承自IClickStrategy并实现GetClicks()方法的类:

public class UnionenClicksController : IClickStrategy
{
    Models.DMDelivery.Unionen model;
    Logger logger;

    public UnionenClicksController()
    {
        this.model = new Models.DMDelivery.Unionen();
        this.logger = new Logger();
    }

    public void GetClicks(string[] args)
    {
        ...
    }
}

On my main method, depending on the type of strategy I would like to decide what to do.So before everything I have: 在我的主要方法上,根据策略的类型,我想决定做什么。所以在我拥有的一切之前:

IStrategy strategy = null;

And then if the input parameters wanted to get clicks information I would like to invoke the GetClicks function from my class UnionenClicksController() . 然后,如果输入参数想获得点击信息,我想从我的类UnionenClicksController()调用GetClicks函数。

在此输入图像描述

But as can be seen, I cannot see the GetClicks() function. 但是可以看出,我看不到GetClicks()函数。 However if I change my strategy to an IClickStrategy , then it will see my GetClicks. 但是,如果我将策略更改为IClickStrategy ,那么它将会看到我的GetClicks。 But that's not what I want because I may have a different strategy other than clicks and I don't want to declare it at the beginning of my main method. 但这不是我想要的,因为除了点击之外我可能有不同的策略,我不想在我的main方法的开头声明它。

What is it that I'm doing wrong? 我做错了什么? Thanks. 谢谢。

IStrategy doesn't contain GetClicks , it is to be found in IClickStrategy interface. IStrategy不包含GetClicks ,它可以在IClickStrategy界面中找到。

Change 更改

IStrategy strategy = null;

to

IClickStrategy strategy = null;

You can also try casting it to proper interface, 您也可以尝试将其转换为适当的界面,

if you are sure that it implements correct interface: 如果你确定它实现了正确的接口:

((IClickStrategy)strategy).GetClicks();

if you are unsure: 如果你不确定:

var s = strategy as IClickInterface;
if (s != null)
{
    s.GetClicks();
}

You have to either cast for each case, or have a virtual method in IStrategy that chooses the right method. 您必须为每个案例进行IStrategy ,或者在IStrategy中使用虚拟方法来选择正确的方法。

The latter solution is impossible if an object implement several strategies. 如果一个对象实现了几种策略,那么后一种解决方

IStrategy strategy = null;

.
.
.  later on you find that you need to see if it contains a IClickStrategy ..
.

IClickStrategy clicker = strategy as IClickStrategy;

if(clicker != null) {
  clicker.GetClicks(...);
}

Try it 试试吧

IClickStrategy strategy = null;

because UnionenClicksController does not inherit IStrategy. 因为UnionenClicksController不继承IStrategy。

Sure you do. 当然可以。 But the compiler doesn't know that. 但是编译器不知道这一点。 You just told him, you want to treat strategy as an IStrategy . 你刚刚告诉他,你想将strategy视为一种IStrategy You were very explicit about that. 你非常清楚这一点。 Now... 现在...

Don't confuse the name strategy with your UnionenClicksControler object - it is just a name for the object. 不要将名称strategyUnionenClicksControler对象混淆 - 它只是对象的名称。 And the name has a type. 这个名字有一个类型。 If you want to get at the GetClicks() method, just do: 如果你想获得GetClicks()方法,只需:

(strategy as IClickStrategy).GetClicks(args);

I have not tried this myself yet, since I haven't got around to, but doing 我自己还没有尝试过这个,因为我没有去过,而是在做

dynamic strategy;

might also solve your problem... but you probably forfeit any IntelliSense magic... 也可能解决你的问题...但你可能会放弃任何智能感知魔法......

Try using this: 试试这个:

if(strategy is IClickStrategy)
    (strategy as IClickStrategy).GetClicks();

Technically you need to check for the type of the object first, then cast it in order to see the inheriting interface's method. 从技术上讲,您需要首先检查对象的类型,然后将其强制转换以查看继承接口的方法。

Thanks for all the answers but I found two solutions to my problem: 感谢所有的答案,但我找到了两个问题的解决方案:

First, is to not use the line: 首先,是不使用该行:

IStrategy strategy = null;

And postpone it until after every switch statement and then declare the strategy as a IClickStrategy. 并将其推迟到每个switch语句之后,然后将策略声明为IClickStrategy。

Second, if I want to keep my IStrategy strategy = null; 第二,如果我想保持我的IStrategy策略= null; line I moved the GetClicks method one level up in my IStrategy interface and gave it a more general name: GetItems . 我在我的IStrategy界面中将GetClicks方法移动了一级并给它一个更通用的名称: GetItems

And now my switch case looks like this: 现在我的开关盒看起来像这样:

case "GETCLICKSUNIONEN":
    strategy = new UnionenClicksController();
    strategy.GetItems(args);                            
    break;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM