定义了接口,里面包含方法,但是又不实现方法。最后还是要在具体的类里面去实现方法。这样岂不是多此一举了吗?这应该只是认识到接口的约束性,没有理解到深层的作用。
假设有个动物园,里面暂时只有狗和猫两种动物。
class Dog { public void Jump() { Console.Write("狗跳"); } } class Cat { public void Jump() { Console.Write("猫跳"); } }
然后定义一个训练员,他具有训练狗和猫的能力。
class Trainer { public void TrainAnimal(Dog dog) { dog.Jump(); } public void TrainAnimal(Cat cat) { cat.Jump(); } }
在动物园中,训练员训练动物跳:
class Zoo { public Zoo() { Dog dog = new Dog(); Cat cat = new Cat(); Trainer trainer = new Trainer(); trainer.TrainAnimal(dog); trainer.TrainAnimal(cat); } }
但是这个时候,动物园里面来了个猪,我们会创建Pig类,同时Trainer类需要(升级)再重载一个方法 TrainAnimal(Pig pig)。
这个时候,又来了个兔子,马,猴子,羊... 这下麻烦大了。人类要反反复复升级。。。
但是如果我们使用接口那么情况就不同了。
interface IAnimal { void Jump(); }
使猫、狗、公鸡都继承这个接口。
class Dog : IAnimal { public void Jump() { Console.Write("狗跳"); } } class Cat : IAnimal { public void Jump() { Console.Write("猫跳"); } } class Cock: IAnimal { public void Jump() { Console.Write("公鸡跳"); } }
训练员修改为:
class Trainer { public void TrainAnimal(IAnimal animal) { animal.Jump(); } }
这个时候,动物园里面训练员训练公鸡就简单了,而且即使动物园再来其他动物,也只需要继承IAnimal接口就可以被训练员训练。
class Zoo { public Zoo() { Dog dog = new Dog(); Cat cat = new Cat(); Cock cock = new Cock(); Trainer trainer = new Trainer(); trainer.TrainAnimal(dog); trainer.TrainAnimal(cat); trainer.TrainAnimal(cock); } }
我们从设计类的方面想。一个项目有很多个类去编写,程序员A会被安排去写Dog类,程序员B会被安排去写Cat类。这两个类本身是没有什么联系的。可是客户需求他们都要实现“跳”这个功能。这就是要对他们进行约束。使用接口之后,Dog和Cat就被约束成必须实现跳。而对于程序员C在编写Trainer类的时候,当他知道动物都继承了IAnimal,他不用关心Cat和Dog是如何实现“跳”,只要让动物“跳”就可以了。