假设有两个类具有相同的道具,在该道具中也有逻辑。
public class Manager
{
private string _ssn { get; set; }
[RegularExpression(@"\d{9}")]
public string SSN
{
get
{
return _ssn;
}
set
{
if (!string.IsNullOrEmpty(value))
_ssn = someLogicalMethod (value);
}
}
}
和
public class Employee
{
private string _ssn { get; set; }
[RegularExpression(@"\d{9}")]
public string SSN
{
get
{
return _ssn;
}
set
{
if (!string.IsNullOrEmpty(value))
_ssn = someLogicalMethod(value);
}
}
}
理想情况下,您将创建一个将继承的抽象基类(BaseSSN)。这一切都很好,但并不理想!原因是因为在C#中你只能从1个超类继承。这意味着如果你有一个Manager和Employee都有SSN,但是Manager和一个新类(CEO)有一个ManagerOf属性的情况,那么你必须创建一个实现BaseSSN类的新类,但它也是一个抽象类(BaseManagerOf),其中包含Managerof的逻辑。然后,经理和首席执行官将继承新课程。但是,如果有人是经理但是他们自己没有SSN,那么现在你必须创建另一个类。你需要拔出经理道具并把它放在一个超级,以将它与SSN类分开。
你知道我要去哪儿吗?根据每个类与其他类相似的道具数量,它可以创建N个变体。
所以我想做的就是简单
公共类管理器:BaseSSN,BaseManagerOf,X
X是什么的。您可以使用接口执行此操作,但接口不能包含逻辑。
我相信可能有一个平稳的策略可以解决这个问题,但无法解决这个问题。
编辑:
关于我的问题,似乎存在一些混淆:这是一个假设的问题。我知道经理是员工。简单的问题是我希望一个类实现2个摘要,而不能在C#中实现。但是,是否有一种策略可以让它以任何方式工作?
public class Manager : BaseManager
{
}
public abstract class BaseManager : BaseSSN
{
private string _managerOf;
public int ManagerOf
{
get
{
return _managerOf;
}
set
{
if (!string.IsNullOrEmpty(value))
_managerOf = someLogicalMethod(value);
}
}
}
public abstract class BaseSSN
{
private string _ssn { get; set; }
[RegularExpression(@"\d{9}")]
public string SSN
{
get
{
return _ssn;
}
set
{
if (!string.IsNullOrEmpty(value))
_ssn = someLogicalMethod(value);
}
}
}
public class CEO : ManagerOf {}
现在它开始与CEO分道扬..我不想要首席执行官的SSN,只需要他管理的人。因此,我必须从继承SSN的ManagerOf类中拉出逻辑,并将其放在自己的类中。那么CEO就不会拥有SSN道具。但是,现在我不能在我的Manager类中同时拥有ManagerOf逻辑和SSN逻辑,而不会创建另一个类似于以下类的抽象...
public class ManagerOfAndSSN: SSN
{
// repetitive manager logic here
}
一个答案是使用接口和组合。实现该功能的“基础”类(例如ManagerOf
或SSN
)实现了接口,然后将它们作为依赖项提供给需要它们的类:
public interface ISsn
{
string Ssn { get; set; }
}
public interface IManagerOf
{
List<Employee> Manages { get; set; }
}
public class Ssn : ISsn { ... }
public class ManagerOf : IManagerOf { ... }
现在,您可以将这些类注入组合它们的类中:
// here we are implementing the interfaces on the class
public class Employee : ISsn
{
private ISsn _ssn;
public Employee(ISsn ssn)
{
_ssn = ssn;
}
public string Ssn
{
get { return _ssn.Ssn; }
set { _ssn.Ssn = value }
}
}
public class Manager : ISsn, IManagerOf
{
private ISsn _ssn;
private IManagerOf _managerOf;
public Employee(ISsn ssn, IManagerOf managerOf)
{
_ssn = ssn;
_managerOf = managerOf;
}
public string Ssn
{
get { return _ssn.Ssn; }
set { _ssn.Ssn = value }
}
public List<Employee> Manages
{
get { return _managerOf.Manages; }
set { _managerOf.Manages = value; }
}
}
或者,类的替代实现:
// here we're just going to expose each dependency as the interface
public class Employee : ISsn
{
private ISsn _ssn;
public Employee(ISsn ssn)
{
_ssn = ssn;
}
public ISsn Ssn => _ssn;
}
public class Manager2
{
private ISsn _ssn;
private IManagerOf _managerOf;
public Employee(ISsn ssn, IManagerOf managerOf)
{
_ssn = ssn;
_managerOf = managerOf;
}
public ISsn Ssn => _ssn;
public IManagerOf ManagerOf => _managerOf;
}
这是一个相当简单的实现,在这种情况下,我选择简单地在支持该功能的每个类中实现接口。但是,如果您在属性周围有更复杂的逻辑,那么组合路由更有意义,因为您正在共享实现。它起初并不像多重继承那样“优雅”,但请参阅Why is Multiple Inheritance not allowed in Java or C#?,讨论为什么多重继承通常被认为会导致比它解决的更多麻烦。