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("我会飞行"); } } /// <summary> /// 绿头鸭 /// </summary> public class MallardDuck : Duck { public override void Display() { Console.WriteLine("外观是绿头"); } } /// <summary> /// 红头鸭 /// </summary> public class RedheadDuck : Duck { public override void Display() { Console.WriteLine("外观是红头"); } } /// <summary> /// 橡皮鸭 /// 吱吱叫 /// 不会飞行 /// </summary> 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("我会飞行"); } } /// <summary> /// 绿头鸭 /// </summary> public class MallardDuck : Duck { public override void Display() { Console.WriteLine("外观是绿头"); } } /// <summary> /// 红头鸭 /// </summary> public class RedheadDuck : Duck { public override void Display() { Console.WriteLine("外观是红头"); } } /// <summary> /// 橡皮鸭 /// 吱吱叫 /// 不会飞行 /// </summary> public class RubberDuck : Duck { public override void Quack() { Console.WriteLine("吱吱叫"); } public override void Fly() { Console.WriteLine("我不会飞行"); } public override void Display() { Console.WriteLine("外观是橡皮鸭"); } } /// <summary> ///诱饵鸭(木头鸭)既不会叫也不会飞 /// </summary> 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(); } /// <summary> /// 绿头鸭 /// </summary> public class MallardDuck : Duck,IQuackAble,IFlyAble { public void Quack() { Console.WriteLine("呱呱叫"); } public void Fly() { Console.WriteLine("我会飞行"); } public override void Display() { Console.WriteLine("外观是绿头"); } } /// <summary> /// 红头鸭 /// </summary> public class RedheadDuck : Duck,IQuackAble,IFlyAble { public void Quack() { Console.WriteLine("呱呱叫"); } public void Fly() { Console.WriteLine("我会飞行"); } public override void Display() { Console.WriteLine("外观是红头"); } } /// <summary> /// 橡皮鸭 /// 吱吱叫 /// 不会飞行 /// </summary> public class RubberDuck : Duck,IQuackAble { public void Quack() { Console.WriteLine("吱吱叫"); } public override void Display() { Console.WriteLine("外观是橡皮鸭"); } } /// <summary> ///诱饵鸭(木头鸭)既不会叫也不会飞 /// </summary> 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(); } } }