【问题标题】:Child use of interface孩子使用界面
【发布时间】:2012-09-18 13:08:50
【问题描述】:

我有一个用户控件来处理表单上的图像。但根据来源(网络摄像头或 ID 扫描或其他视频来源),用户控制是不同的。

但是它们有一些共同的特性,所以我想创建一个基类。

我的其他控件都有一些我需要的界面项。我想在基础级别声明接口,并在类级别实现。但 virtual 和 override 似乎是获得我想要的最接近的方式。有没有办法,强制新类实现基类分配的接口?环顾四周,让类抽象化(我不完全理解)可能是一个开始。如果只是方法可能没问题,但我也在使用属性。在那个领域,我在寻找答案时遇到了死胡同。这是我到目前为止所拥有的。我在正确的轨道上吗?我只是根本没有使用过抽象类,只接触过有限的接口。根据研究,我认为我的方法是正确的,只是不确定该属性。

  public interface RequiredAnswer
  {
    void LabelRequiredFieldEmpty();
    bool AnswerRequired{ get;}
  }


  public abstract partial class ExtImage : UserControl, RequiredAnswer
  {
    public virtual bool AnswerRequired
    {
      get
      {
         throw new NotImplementedException ("Answer Required");
      }
    }
    public abstract void LabelRequiredFieldEmpty ()
    {
        //checkBox_AgreementAcceptedText.ForeColor = Color.Red;
    }

所以我会上课

  public partial class ExtImageWebCam : ExtImage
  {
    public override bool AnswerRequired
    {
      get
      {
        return valueFromThisClassThatMeansAnAnswerIsRequired;
      }
    }

     public override void LabelRequiredFieldEmpty ()
     {
       // do something 
     }    
  }

【问题讨论】:

  • 这是一种奇怪的大括号样式还是需要有人进行编辑?
  • 我去看看,不是故意的
  • 看起来有人已经编辑过了谢谢@BZink

标签: c# interface abstract-class base-class


【解决方案1】:

当您声明方法抽象时,您基本上是在说子类必须提供方法的定义。您可以使属性抽象。这听起来正是您所需要的。

这里是MSDN 文章供进一步参考。

来自 MSDN

属性

抽象属性的行为类似于抽象方法,但声明和调用语法有所不同。

在静态属性上使用抽象修饰符是错误的。

通过包含使用 override 修饰符的属性声明,可以在派生类中覆盖抽象继承属性。

稍后继续

在此示例中,类 DerivedClass 派生自抽象类 BaseClass。抽象类包含一个抽象方法 AbstractMethod 和两个抽象属性 X 和 Y。

abstract class BaseClass   // Abstract class
{
    protected int _x = 100;
    protected int _y = 150;
    public abstract void AbstractMethod();   // Abstract method
    public abstract int X    { get; }
    public abstract int Y    { get; }
}

带有接口的抽象基类

抽象类必须为所有接口成员提供实现。

实现接口的抽象类可能会将接口方法映射到抽象方法。例如:

interface I
{
    void M();
}
abstract class C : I
{
    public abstract void M();
}

【讨论】:

  • 我读过那篇文章,但它没有(或者我没有看到)讨论接口的属性。我没有排除您的正确答案,因为它没有涵盖界面,而另一个答案 @DStanley's 涵盖了。
  • @Brian 我很高兴 DStanley 能够提供帮助。我从 MSDN 中复制了与抽象属性相关的部分以供将来参考。
【解决方案2】:

首先,按照惯例,接口应以I 开头,因此您的接口应为IRequiredAnswer

其次,如果你想强制继承的类实现自己的方法而不是继承它们,只需在基类中将它们抽象:

public abstract class ExtImage : UserControl, IRequiredAnswer
{
    public abstract bool AnswerRequired  { get; }

    public abstract void LabelRequiredFieldEmpty ();
}

然后您的子类必须实现方法和属性。

【讨论】:

  • 由于我不使用接口,我感谢您提供“我按照惯例”的信息
  • 感谢您的快速回答。看起来这就是我所需要的。我不知道我是否可以使接口所需的属性抽象,但它确实很有意义。
【解决方案3】:

你在正确的轨道上。这是您可以做什么的简单示例。将 Bar() 方法抽象化会强制继承者实现它。

public interface IFoo{
    void Bar();
}

public abstract class BaseFoo : IFoo
{
    public abstract void Bar();

    public void Implemented(){
        Debug.WriteLine("this is a shared implementation");
    }
}

public class KungFoo : BaseFoo{
    public override void Bar()
    {

    }
}

【讨论】:

    【解决方案4】:

    您在创建接口然后为您的目的定义一个抽象类的正确轨道上。

    接口的标准命名约定已被打破,但是接口通常以 I 为前缀以帮助识别它们

    public interface IRequiresAnswer
    {
       void LabelRequiredFieldEmpty();
       bool AnswerRequired { get;  }
    }
    

    我还建议将 AnswerRequired 属性更改为一个函数,因为您的具体类说“做某事以找到结果”。属性通常意味着快速,因此在属性中执行任何计算都会掩盖调用属性时发生的实际工作。使用函数时,调用者会更清楚地看到结果不会立即得到。

    【讨论】:

    • 该属性的好点,在示例中我很草率。我会编辑。
    • 不确定我是否同意关于“快速”属性的说法。如果没有副作用(意味着访问属性不会影响其他属性),那么我认为在幕后进行一些处理没有问题。单例模式是一个不简单地返回值的属性示例。
    • @DStanley 根据MSDN article 中的属性与方法部分,当操作成本高到足以表明本地缓存结果并不快时,应使用方法。
    • 嗯,“足够贵”是任意的。我绝对认为按照您的建议使用“任何计算”的方法是矫枉过正的。
    • 我的示例代码并不清楚它要做什么,所以我认为我的示例中的措辞正确地用 JGinSD 提出了一个标志。但我也认为 DStanley 指出“任何”是广泛的是有效的。我认为最好将其更改为“过于复杂”或“过于耗时”。双方的对话都很好!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-08-10
    • 1970-01-01
    • 2021-07-04
    • 2020-08-18
    • 2017-04-22
    • 2014-03-27
    相关资源
    最近更新 更多