如何将接口调用委托给实现接口的成员
本文关键字:接口 实现 成员 调用 | 更新日期: 2023-09-27 18:27:43
假设我有一个接口ICry,它有返回动物声音的函数:
public interface ICry
{
string Cry();
}
我有几个实现ICry的类:类别类别:ICry{公共字符串Cry{get{return"Meow!";}}}
class Dog: ICry
{
public string Cry { get { return "Woof"; } }
}
如果我有一个宠物主人对象拥有一只宠物,并且我知道这个宠物主人会哭(),但想隐藏他是如何哭的,我可以做以下操作:
class PetOwner : ICry
{
private Cat cat = new Cat();
public string Cry() {return cat.Cry();}
}
那么用法是:
PetOwner john = new PetOwner();
console.WriteLine(john.Cry());
到目前为止一切都很好,西线一切都很平静
但是如果ICry有很多功能该怎么办呢。使用此方法需要为所有ICry函数实现PetOwner函数。尽管这些函数只会调用Cat.ICry的相应函数,但仍然会有很多无用的工作。
有什么模式可以防止这种情况发生吗?
您之所以选择使用接口而不是派生,是因为您想隐藏某些事情是如何完成的。如果你想表达一个类能够做一些事情,你可以使用一个接口。在这种情况下,你想证明约翰有能力发出动物的声音。
这里也提出了同样的问题:使用成员作为实现实现接口
那里的解决方案是从猫那里得到宠物主人。但是如果必须实现两个接口呢?从两个类派生?
此外,宠物主人不是猫。猫可以做很多宠物主人可能做不到的事情。
链接中给出的解决方案之一是从宠物主人那里删除ICry,并为宠物主人提供一个获取猫的属性,然后调用猫的ICry函数:
class PetOwner
{
private Cat cat = new Cat();
public Cat Cat {return cat;}}
}
用法是:
PetOwner John = new PetOwner();
John.Cat.Cry();
使用这种方法,宠物主人的用户必须知道宠物主人不会自己哭,而是用他的猫哭。
问题是,如果你的宠物主人决定扔掉猫,买一只狗,你的代码就不起作用了。您使用ICry接口的计划不起作用。
如果你真的想隐藏PetOwner是如何哭泣的,但你不想实现ICry的所有功能,不要实现接口,而是实现一个get属性,它会给你一个实现ICry接口的对象。像这样:
interface ICry
{
string Cry { get; }
}
class Cat : ICry
{
public string Cry { get { return "Meow!"; } }
}
class Dog: ICry
{
public string Cry { get { return "Woof"; } }
}
class PetOwner
{
private Cat cat = new Cat();
public ICry ICry {get{return cat;}}
}
用法:
PetOwner John = new PetOwner();
John.ICry.Cry();
现在你不知道约翰是怎么哭的。你只知道约翰会注意Cry()的完成。因此,如果John决定带一只狗,并决定从现在起,狗将不得不哭泣(),用户不必更改:
class PetOwner
{
private Cat cat = new Cat();
private Dog dog = new Dog();
public ICry ICry {get{return dog;} }
}
用法未更改:宠物主人约翰=新宠物主人();John.ICry.Cry();
即使约翰决定除掉所有的动物并亲自哭泣,用户也不必改变:
class PetOwner : ICry // The petowner has decide to Cry himself
{
public ICry ICry {get{return this;}}
public string Cry { get { return "Hello!"; } }
}
用法仍然没有改变:宠物主人约翰=新宠物主人();John.ICry.Cry();