【问题标题】:Do inheritance right做正确的继承
【发布时间】:2011-07-13 15:47:08
【问题描述】:

我有课:

internal class Stage
{
    public long StageId { get; set; }
    public string StageName { get; set; }
    public int? Order { get; set; }

    public Stage()
    {
        Order = 0;
    }
}

我也有:

public class GroupStage : Stage
{
    private override long StageId { set { StageId = value; } }

    public GroupStage() : base() { }

    public void InsertStage(long groupId)
    {
    }

    public static void SetStageOrder(long stageId, int order)
    {
     ....
    }

    public static void DeleteStage(long stageId)
    {
     ....
    }

    public static GroupStage[] GetStages(long groupId)
    {
     ....
    }
}

和:

public class TaskStage : Stage
{
    public DateTime? Time { get; set; }

    public TaskStage()
        : base()
    {
     ....
    }

    public static Stage GetNextTaskStage(Guid companyId, long taskId)
    {
     ....
    }

    public static Stage[] GetTaskStages(Guid companyId, long taskId)
    {
     ....
    }
}

这不起作用,我得到了异常: 可访问性不一致:基类 Stage 的可访问性低于类 GroupStage

我希望 Stage 类是私有的,并且除了 GroupStageTaskStage 之外没有访问权限。我还想让StageIdGroupStageTaskStage 中成为私有的。 我怎样才能做到这一点而不在GroupStageTaskStage 中重复Stage 的成员?

【问题讨论】:

  • “正确继承” .. 好的,那么您的行为在哪里?
  • 对不起,我不明白你的问题。
  • 您在问如何正确地进行继承,但您的类没有任何行为(除了一些静态 CRUD/ActiveRecord)。如果您想“正确地进行继承”,您的设计将围绕您的类中的行为,而不是属性包。换句话说,我是说你做错了。大错特错。
  • 您似乎只是为了使用继承而使用继承。当我看到您的基类只包含基本属性时,这是严重的代码臭味。在您使用的示例中没有继承意义。然后是所有的静态方法......另一种代码味道。而且您似乎对可访问性级别过于关注。我并不是要贬低,因为您似乎对 OO 有点陌生,但您似乎在设计上犯了一些相当严重的错误。
  • 你怎么可以让派生类(StageId)中的属性更难访问?有人愿意解释吗?会很感激的。

标签: c# inheritance business-objects


【解决方案1】:

您需要将 Stage 类设为公开或受保护。如果你把它抽象化,它就不能在那个级别上实例化,所以如果它是公共的,你不必担心它被创建为基类

【讨论】:

    【解决方案2】:

    将其设为 protected 而不是私有的。如果将其设置为受保护,则可以让从它继承的类调用基类上的方法,并继承基类成员。

    【讨论】:

    • 然后我得到:命名空间中定义的元素不能显式声明为私有、受保护或受保护。
    【解决方案3】:

    你不能让派生类比它的基类更容易访问。您可以做的是将 TaskStage 和 GroupStage 也设为内部,然后继承并公开公共接口,以便只有该接口在您的程序集之外可见。

    public interface IGroupStage
    {
        public string StageName{ get; set; }
        ...
    }
    
    interal class GroupStage : IGroupStage
    {
    ...
    }
    

    【讨论】:

    • 在这个解决方案中,我最终得到了 5 个文件。我怎样才能把它们安排在我的图书馆里?哪些文件将在哪个文件夹下?这种方法在文件数量方面非常复杂。
    • 正确的 OOP 通常会导致文件数量增加。
    • 5 个文件在现实世界中不算什么。我花了一段时间才克服对许多文件的恐惧,然后我意识到没有理由有这种恐惧。只需使用文件夹。在这种情况下,我会将所有 5 个文件放在同一个文件夹中。也许是“阶段”文件夹。 Visual Studio 也会自动将它们放入子命名空间中,我喜欢这样。
    • @Paul Alexander:你能解释一下如何做,并参考我应该为每个文件/类指定的文件夹和名称吗?
    • @Naor:记住源代码是给开发者的。因此,以任何对您有意义的布局来安排源。如果将文件组织到单独的文件夹中对您有意义,请执行此操作。 Visual Studio 并不在乎。就我个人而言,我可能会将接口和类定义放在同一个文件中,这样在我开发时更容易向两者添加方法/属性。
    【解决方案4】:

    您可能真正想要的是 Stage 是一个抽象基类,因此无论其可访问性修饰符如何,都不能直接实例化。改变你对舞台的定义:

    public abstract class Stage
    {
        protected long StageId { get; set; }
        public string StageName { get; set; }
        public int? Order { get; set; }
    
        protected Stage()
        {
            Order = 0;
        }
    }
    

    protected 修饰符意味着您的派生类将能够访问该成员,但不能在这些类之外访问它。

    【讨论】:

      猜你喜欢
      • 2023-03-16
      • 2016-11-05
      • 2017-01-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-11
      相关资源
      最近更新 更多