删除对继承的抽象类引用的依赖

时间:2015-05-28 19:04:38

标签: c# .net inheritance abstract-class

我正在尝试设置一个场景,我们可以为我们的工作组创建一组通用模型,然后在需要时实现或扩展它们。

我有以下设置:

namespace Workgroup.DomainClasses
{
    public abstract class WorkGroupOrder
    {
       private ICollection<WorkGroupItems> _items;

       protected WorkGroupOrder()
       {
           _items = new List<WorkGroupItems>();
       }
       protected int OrderId { get; set; }
       protected virtual ICollection<WeAccount> Items
       {
           get { return _items; }
           set { _items = value; }
       }
    }
}

我希望用户不使用基础WorkGroupOrder,因此想要设置它,以便他们需要实现自己的类版本。如果对基类都很好,那么它只是一个调用基础构造函数的空类,但是可以添加属性和功能。这样做的想法是,工作组域比单个项目可能需要的大得多,但我们希望从这个通用模型中推动所有工作。

using Workgroup.DomainClasses;
namespace Project.DomainClasses
{
    public class Order : WorkGroupOrder
    {
        public string OrderComment { get; set; }
    }
}

我遇到的问题是我需要引用两个域模型来实现。在Testing()方法中有一个错误,我必须引用Workgroup.DomainClasses来实例化类。我不熟悉抽象类,所以这只是抽象类型的本质吗?如果可能的话,我宁愿删除这种依赖。

using Project.DomainClasses;
namespace Project.DataLayer
{
    public class Testing
    {
        public void Testing()
        {
            Order o1 = new Order();
        }
    }
}

几个问题。

  1. 这个组织是否有意义或是否有更好的方法     支持我提供可能潜在的共同模型的愿望     被延长?
  2. 我如何访问基础的属性     抽象类和具体类?在我的Testing()方法中,我无法做到     例如,访问`o1.OrderId`。
  3. 我想从开发人员中删除抽象类的元知识。在没有明确要求开发人员这样做的情况下执行构造函数最好如何?

最终,我想要求开发人员创建自己的类实例,以避免直接实现基本模型。我还希望建立适当的可见性,以防止它们直接进入Workgroup对象。

2 个答案:

答案 0 :(得分:2)

似乎这里有一些不同的问题。

首先,使用命名空间来尝试隔离基本功能不是一个可行的选择,因为默认情况下所有派生类都需要访问基类的命名空间(为了继承)。任何扩展基类的开发人员都需要访问包含基类的命名空间。

通常最好使用访问修饰符(例如publicprotectedprivate)或带有public get{ }和{{的公共属性来控制对功能或数据的访问权限1}}或protected set{ }(即具有不同访问级别的getter和setter)。如果您希望隐藏最终用户的实施细节,那么private set{ }是正确的方法(例如API)。

其次,通过标记任何类interface,您将自动拒绝其他开发人员直接实例化该类的能力。为了使用abstract基类的方法和属性,他们将被迫创建一个派生自abstract类(又名&#34;具体&#34;类)的类。

第三,您无法在测试代码中访问属性abstract的原因是因为该属性的访问修饰符为o1.OrderId。这意味着只有基类及其派生类可以内部访问此属性。要将其公开给最终用户,必须将其标记为protected

答案 1 :(得分:2)

不幸的是,我真的不明白你的意思是“设置一个场景,我们可以为我们的工作组创建一组通用模型,然后在需要时实现或扩展它们”。您的上下文中的工作组是什么?为什么(所有)其他类派生于它?

无论如何,你不能使用o1.OrderID,因为这个属性是protected,这意味着它只在WorkOrderGroup范围内可见,并且是从它派生的子类。创建此属性public,您可以随处访问它。

此外,请不要冒犯,但它会让你在面向对象的封装和继承概念方面有些困难。我建议你看看这些概念(例如,你可以开始here),并在实现功能时很好地理解它们的作用以及如何使用它们。 根据您当前的信息,我建议您不要像在问题中解释的那样构建代码。

最后,一些关于面向对象语言实践的一般性提示:

  • 支持组合而不是继承:这意味着您应该通过封装它们而不是从它们继承来扩展现有类。在大多数情况下,这更灵活。
  • 看看SOLID原则:它们提供了非常好的指示,你应该在你写的每个课程上考虑这些指示。
  • 看一下设计原则,也许是领域驱动设计:网上有很多指导,有很多例子。通过每个示例,您可以更好地了解如何处理新问题以及如何在OOD中对其进行建模。

我希望这个答案可以指导你正确的方向。