using System;using System.Collections.Generic;using System.Linq;using System.Text;namespace SmiUDuck{ class Program { public abstract class Duck { public void Quack() { Console.WriteLine("呱呱叫"); } public void Swim() { Console.WriteLine("游泳"); } public abstract void Display(); //我们需要让鸭子能飞 //但并非所有Duck所有派生类都会飞。 //在Duck超类中加上新的行为,会是的某些并不适合该行为的子类也具有该行为 //对代修改码所做的局部修改,影响面可不只是局部的(会飞的橡皮鸭) public void Fly() { Console.WriteLine("我会飞行"); } } ////// 绿头鸭 /// public class MallardDuck : Duck { public override void Display() { Console.WriteLine("外观是绿头"); } } ////// 红头鸭 /// public class RedheadDuck : Duck { public override void Display() { Console.WriteLine("外观是红头"); } } ////// 橡皮鸭 /// 吱吱叫 /// 不会飞行 /// public class RubberDuck : Duck { public override void Display() { Console.WriteLine("外观是橡皮鸭"); } } static void Main(string[] args) { Duck duck; duck = new MallardDuck(); duck.Display(); duck.Quack(); duck.Swim(); duck.Fly(); Console.WriteLine(); duck = new RedheadDuck(); duck.Display(); duck.Quack(); duck.Swim(); duck.Fly(); Console.WriteLine(); //现在橡皮鸭呱呱叫还会飞行和橡皮鸭的行为不相符。 duck = new RubberDuck(); duck.Display(); duck.Quack(); duck.Swim(); duck.Fly(); Console.ReadKey(); } }}
运行截图
(二)利用继承添加橡皮鸭和诱饵鸭满足这两种情况下鸭子的行为
为了让橡皮鸭吱吱叫,且不会飞行将Duck超累中的Quck()和Fly()弄成virtual类型。让橡皮鸭RubberDuck继承Duck超类,在Rubber中重写Quack()方法和Fly()方法,用这样继承貌似这样可以解决问题。
但是如果加入诱饵鸭(木头鸭)既不会叫也不会飞,同样需要重写Quack()方法和Fly()方法,要是后续还有很多其他类型的鸭子,这样会重写Quack()方法和Fly()方法,会大大增加代码量。
利用继承Duck来提供Duck的行为,这会导致如下缺点(1)代码在多个子类中重复 (2) 运行时行为不容易改变 (3)很难知道所有鸭子的全部行为using System;using System.Collections.Generic;using System.Linq;using System.Text;//为了让橡皮鸭吱吱叫,且不会飞行//将Duck超累中的Quck()和Fly()弄成virtual类型。让橡皮鸭RubberDuck继承Duck超类,在Rubber中重写Quack()方法和Fly()方法//用这样继承貌似这样可以解决问题,但是如果加入诱饵鸭(木头鸭)既不会叫也不会飞//同样需要重写Quack()方法和Fly()方法//要是后续还有很多其他类型的鸭子,这样会重写Quack()方法和Fly()方法,会大大增加代码量//利用继承Duck来提供Duck的行为,这会导致如下缺点//(1)代码在多个子类中重复// (2) 运行时行为不容易改变// (3)很难知道所有鸭子的全部行为namespace SmiUDuck2{ class Program { public abstract class Duck { public virtual void Quack() { Console.WriteLine("呱呱叫"); } public void Swim() { Console.WriteLine("游泳"); } public abstract void Display(); //我们需要让鸭子能飞 //但并非所有Duck所有派生类都会飞。 //在Duck超类中加上新的行为,会是的某些并不适合该行为的子类也具有该行为 //对代修改码所做的局部修改,影响面可不只是局部的(会飞的橡皮鸭) public virtual void Fly() { Console.WriteLine("我会飞行"); } } ////// 绿头鸭 /// public class MallardDuck : Duck { public override void Display() { Console.WriteLine("外观是绿头"); } } ////// 红头鸭 /// public class RedheadDuck : Duck { public override void Display() { Console.WriteLine("外观是红头"); } } ////// 橡皮鸭 /// 吱吱叫 /// 不会飞行 /// public class RubberDuck : Duck { public override void Quack() { Console.WriteLine("吱吱叫"); } public override void Fly() { Console.WriteLine("我不会飞行"); } public override void Display() { Console.WriteLine("外观是橡皮鸭"); } } //////诱饵鸭(木头鸭)既不会叫也不会飞 /// public class DecoyDuck : Duck { public override void Quack() { Console.WriteLine("不会叫"); } public override void Fly() { Console.WriteLine("不会飞行"); } public override void Display() { Console.WriteLine("外观是橡皮鸭"); } } static void Main(string[] args) { Duck duck; duck = new MallardDuck(); duck.Display(); duck.Quack(); duck.Swim(); duck.Fly(); Console.WriteLine(); duck = new RedheadDuck(); duck.Display(); duck.Quack(); duck.Swim(); duck.Fly(); Console.WriteLine(); duck = new RubberDuck(); duck.Display(); duck.Quack(); duck.Swim(); duck.Fly(); Console.WriteLine(); duck = new DecoyDuck(); duck.Display(); duck.Quack(); duck.Swim(); duck.Fly(); Console.ReadKey(); } }}
(三)利用接口
我们可以把Fly()从超类中提出出来放在IFlyAble接口中,只有会飞的鸭子才实现此接口,同样可以设计一个IQuackAble,虽然IFlyable与Quaackable可以解决“一部分”问题(不会再有会飞的橡皮鸭)。但是代码无法复用。甚至会飞的鸭子中,飞行的动作可能还有多种变化。
using System;using System.Collections.Generic;using System.Linq;using System.Text;//利用接口//我们可以把Fly()从超类中提出出来放在IFlyAble接口中,只有会飞的鸭子才实现此接口,同样可以设计一个IQuackAble//虽然IFlyable与Quaackable可以解决“一部分”问题(不会再有会飞的橡皮鸭)。但是代码无法复用。甚至会飞的鸭子中,飞行的动作可能还有多种变化namespace SimUDuck3{ class Program { public interface IFlyAble { void Fly(); } public interface IQuackAble { void Quack(); } public abstract class Duck { public void Swim() { Console.WriteLine("游泳"); } public abstract void Display(); } ////// 绿头鸭 /// public class MallardDuck : Duck,IQuackAble,IFlyAble { public void Quack() { Console.WriteLine("呱呱叫"); } public void Fly() { Console.WriteLine("我会飞行"); } public override void Display() { Console.WriteLine("外观是绿头"); } } ////// 红头鸭 /// public class RedheadDuck : Duck,IQuackAble,IFlyAble { public void Quack() { Console.WriteLine("呱呱叫"); } public void Fly() { Console.WriteLine("我会飞行"); } public override void Display() { Console.WriteLine("外观是红头"); } } ////// 橡皮鸭 /// 吱吱叫 /// 不会飞行 /// public class RubberDuck : Duck,IQuackAble { public void Quack() { Console.WriteLine("吱吱叫"); } public override void Display() { Console.WriteLine("外观是橡皮鸭"); } } //////诱饵鸭(木头鸭)既不会叫也不会飞 /// public class DecoyDuck : Duck { public override void Display() { Console.WriteLine("外观是诱饵鸭(木头鸭)"); } } static void Main(string[] args) { MallardDuck mallardDuck = new MallardDuck(); mallardDuck.Display(); mallardDuck.Quack(); mallardDuck.Swim(); mallardDuck.Fly(); Console.WriteLine(); RedheadDuck redheadDuck = new RedheadDuck(); redheadDuck.Display(); redheadDuck.Quack(); redheadDuck.Swim(); redheadDuck.Fly(); Console.WriteLine(); RubberDuck rubberDuck = new RubberDuck(); rubberDuck.Display(); rubberDuck.Quack(); rubberDuck.Swim(); Console.WriteLine(); DecoyDuck decoyDuck = new DecoyDuck(); decoyDuck.Display(); decoyDuck.Swim(); Console.ReadKey(); } }}