使用成员作为实现者来实现接口
本文关键字:实现 接口 实现者 成员 | 更新日期: 2023-09-27 17:58:45
我有一个实现IA的类A。
现在我需要创建类B,它也应该实现IA。类B有类A的实例作为成员。
有什么方法可以定义A的实例实现B类中的IA吗?
interfase IA {
void method1();
void method2();
.
.
.
.
void methodN();
}
class A:IA {
public void method1(){}
public void method2(){}
.
.
.
.
public void methodN(){}
}
class B:IA {
private IA m_a;
public B(IA a) {
m_a=a;
}
//Instead all of this I am looking of a way to define that m_a is the implement to IA of B
public void method1(){ use of a.method1 }
public void method2(){ use of a.method2 }
.
.
.
.
public void methodN(){ use of a.methodN }
}
实际上,您可能想要定义某种返回IA
成员的接口,比如Enumerable
/Enumerator
模式。
public interface IB
{
public IA Item { get; }
}
然后B可以简单地返回您存储在其中的实例
public class B : IB
{
public IA Item { get; private set; }
}
A
甚至可以实现IB
public class A : IA, IB
{
public void Method1();
//...
public void MethodN();
IA IB.Item
{
get
{
return this;
}
}
}
如果B
真的应该实现IA
,那么B
必须逐个重新定义每个接口方法,即使每个实现只是对封装的A
成员的实现的调用。
然而,有一种懒惰的方法可以阻止你做所有这些乏味的事情,从实用的角度来看,这几乎是一样的:
class Program
{
static void Main(string[] args)
{
CatOwner Bob = new CatOwner();
Console.WriteLine(((Cat)Bob).Cry);
Console.ReadKey();
}
}
interface ICry
{
string Cry { get; }
}
class Cat : ICry
{
public string Cry { get { return "Meow !"; } }
}
class CatOwner
{
private Cat _MyCat;
public CatOwner()
{
_MyCat = new Cat();
}
public static implicit operator Cat(CatOwner po)
{
return po._MyCat;
}
}
CatOwner
并没有真正实现Cry
,因为猫主人不是那个会叫的人:他的猫会。但作为一种近似,我们可以认为,通过要求猫主人哭,我们当然意味着这种要求实际上是针对他的猫,而不是主人本身。然后我们"把猫主人交给他的猫",然后我们可以让他成为Cry
。
这很有趣,不是吗?:-)
编辑:
也就是说,马格努斯的回答非常值得IMHO考虑。如果考虑到语义上下文,传递成员是可以的,那么它看起来更符合逻辑,也更干净。如果B
只是A
的一种增强变体,不能继承(密封),或者在这样一个特定的上下文中,我的解决方案可能仍然很有趣。。。实际上取决于上下文和语义约束。。。
从A派生B就是您所需要的。
class B:A {
public B() {
}
}
您基本上有两个选项:从A
继承,或者封装A
。这基本上就是两种设计模式之间的区别:封装和继承。
不确定,但为什么要从IA继承类B?你已经在类B中有了对象A的一个实例,你可以使用它。。。
在属性中公开"实现者"而不是B实现接口如何。
class B
{
public IA Implementer {get; private set;}
public B(IA a)
{
Implementer = a;
}
}
从设计的角度来看你的问题,这是一个完全有效的问题(在更复杂的现实生活中),如果只说成员m_a是实现B
我不太同意从A那里继承B的建议:1-在现实生活中,B可以从另一个不相关的类继承,或者说你正在实现IC和ID,并且有成员m_c和m_d。如果能够将c的实现指向m_c,将实现fo ID指向m_d,那就太好了。。等2-用继承代替聚合通常是一个糟糕的设计。
不过这个主意不错。。