Interface笔记
Abstract的问题:
- Abstract也许看上去优美,有一般methrod,virtual methord,或者abstract metho
1 abstract class Car 2 { 3 abstract public void tALK(); 4 public void Drive() 5 { 6 Console.WriteLine("WROOOOOOM"); 7 } 8 public virtual void TruboBosst() 9 { 10 Console.WriteLine("Styuff and things!"); 11 } 12 }
- 有问题,首先you can't inherate from more than one type,其次这样的规则形成了父类可能要写很长,并且make some changes will break all inherate class.问题三,继承存在冲突,看下面示例,如果一辆车即是可以移动又要可以买怎么办?
View Code
1 abstract class Purchasedable 2 { 3 4 } 5 abstract class Moveable 6 { 7 8 } 9 abstract class Car 10 { 11 abstract public void tALK(); 12 public void Drive() 13 { 14 Console.WriteLine("WROOOOOOM"); 15 } 16 public virtual void TruboBosst() 17 { 18 Console.WriteLine("Styuff and things!"); 19 } 20 }
- 再比如椅子的例子
View Code
1 abstract class Purchasedable 2 { 3 4 } 5 abstract class Moveable : Purchasedable 6 { 7 8 } 9 abstract class Car : Moveable 10 { 11 abstract public void Talk(); 12 public void Drive() 13 { 14 Console.WriteLine("WROOOOOOM"); 15 } 16 public virtual void TruboBosst() 17 { 18 Console.WriteLine("Styuff and things!"); 19 } 20 } 21 class Chair : Moveable 22 { 23 //所有的chair都要是可以一定的,但并不需要所有多有价钱,这样就有问题了 24 } 25 class Menu : Purchasedable 26 { 27 28 } 29 class Car1 : Car 30 { 31 public override void Talk() 32 { 33 34 } 35 }
- 可以abstract和interface同时使用,因为abstract可以有common methord在里面,所以abstract可以继承多个interface(想成可以连接任意多个abstract),然后再写入要re-use的 methord,这样继承这个abstract就同时有了两个优点
理解:
- interface can not have implementation in it
- interface have no excutable code in it
- 名字加I
- 比abstract更小,只有定义
- interface可以放property,methord,event, 不可以有field
View Code
1 interface IMoveable 2 { 3 void Move(); 4 } 5 interface IBuyable 6 { 7 decimal Price { get; } 8 void Buy(); 9 }
- 所有的member都是abstract的,所有的一切(包括内部定义的setter)都是public的。member的访问类型可以不加默认是Public的,内部的setter也可以不加,但是要注意继承类都要加回去。有一个问题继承类的实现部分要是private的setter,interface里不要写set关键字,所以记住interface里的property最好setter都不写
View Code
1 interface IMoveable 2 { 3 void Move(); 4 } 5 interface IBuyable 6 { 7 decimal Price { get; } //不写关键字 8 void Buy(); 9 } 10 class Car : IMoveable, IBuyable 11 { 12 public Car( decimal price) 13 { 14 Price = price; 15 } 16 public decimal Price { get; private set; } 17 18 public void Move() 19 { 20 Console.WriteLine("This car can move"); 21 } 22 23 public void Buy() 24 { 25 Console.WriteLine("I buy this car, using ${0}", Price); 26 }
- 把abstract关键字去掉,把访问类型关键字去掉,并且去掉field和具体的implementation就成了interface了
- 继承interface的类的实现(继承类只能是public的(默认可以不用写),不可以是private或者protect的)
View Code
1 class Car : IMoveable, IBuyable 2 { 3 public Car( decimal price) 4 { 5 Price = price; 6 } 7 public decimal Price { get; private set; } 8 9 public void Move() 10 { 11 Console.WriteLine("This car can move"); 12 } 13 14 public void Buy() 15 { 16 Console.WriteLine("I buy this car, using ${0}", Price); 17 } 18 }
- 区分interface inherate,class inherate, class inherate interface
实例1:解决有共同type交集的collection在runtime下还含有各自不同type的问题
View Code
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 6 namespace ConsoleApplication6 7 { 8 interface IItem 9 { 10 string Name { get; } 11 } 12 interface IMoveable 13 { 14 void Move(); 15 } 16 interface IBuyable 17 { 18 decimal Price { get; } 19 void Buy(); 20 } 21 class Car : IItem, IMoveable, IBuyable 22 { 23 24 public decimal Price { get; private set; } 25 public string Name { get; private set; } 26 public Car(string name, decimal price) 27 { 28 Price = price; 29 Name = name; 30 } 31 32 public void Move() 33 { 34 Console.WriteLine("This car can move"); 35 } 36 37 public void Buy() 38 { 39 Console.WriteLine("I buy this car, using ${0}", Price); 40 } 41 } 42 class Chair : IItem, IMoveable 43 { 44 45 public string Name 46 { 47 get; 48 private set; 49 } 50 public Chair(string name) 51 { 52 Name = name; 53 } 54 public void Move() 55 { 56 Console.WriteLine("Moving the chair {0}", Name); 57 } 58 } 59 class Program 60 { 61 static void Main(string[] args) 62 { 63 var items = new List<IItem>(); 64 items.Add(new Car("Small Truck", 32.45m)); 65 items.Add(new Chair("Golden Chair")); 66 items.Add(new Car("Big Coco", 123.99m)); 67 items.Add(new Car("Luxary Dip", 41.5511m)); 68 items.Add(new Chair("Funny Chair")); 69 70 while(true) 71 { 72 73 74 75 76 var chosenItem = ChooseItem(items); 77 var moveable = chosenItem as IMoveable; 78 var buyable = chosenItem as IBuyable; 79 Console.WriteLine("What you want me to do?"); 80 81 var input = Console.ReadLine(); 82 if (buyable != null && input == "buy") 83 { 84 buyable.Buy(); 85 } 86 else if (moveable != null && input == "move") 87 { 88 moveable.Move(); 89 } 90 else 91 { 92 Console.WriteLine("Invalid"); 93 } 94 95 } 96 97 Console.ReadLine(); 98 } 99 100 static IItem ChooseItem(List<IItem> items) 101 { 102 while (true) 103 { 104 var index = 1; 105 foreach (var item in items) 106 { 107 Console.Write("[{0}] - {1}", index, item.Name); 108 109 //Iterface最重要的一点是可以换type,换方法集。 110 //其实这里buyable和item指向的都是同一个对象 111 //根据assign的type不同便可以assign不同member 112 //其实每个item是更具体化的集合 113 //如果是car他便可以是IBuyable,IMoveable或者IItem 114 var buyable = item as IBuyable; 115 116 if (buyable != null) 117 { 118 Console.Write("- cost {0}", buyable.Price); 119 } 120 121 var moveable = item as IMoveable; 122 //使用as可以新做一个临时的var,待右边等式成立把convert好的type传到左边 123 //如果as可行,it will type the object as you ask it to 124 //如果as不avaliable则返回null 125 //as解决了run time type of object的问题 126 127 //Ibuyable buyable = (IBuyable)item; 128 //上面也可行但是如果item不是Ibuyable抛出异常 129 130 if (moveable != null) 131 { 132 Console.Write("- can move"); 133 } 134 Console.WriteLine(); 135 index++; 136 } 137 138 Console.Write("Choose items: "); 139 var itemIndex = int.Parse(Console.ReadLine()); 140 if (itemIndex <= 0 || itemIndex > items.Count) 141 { 142 Console.WriteLine("You are dumb"); 143 continue; 144 } 145 return items[itemIndex-1]; 146 } 147 } 148 } 149 }
实例2:
准备好Icommand和Istate接口
View Code
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 7 namespace ConsoleApplication1.Abstract 8 { 9 interface ICommand 10 { 11 void Execute(); 12 } 13 } 14 15 16 using System; 17 using System.Collections.Generic; 18 using System.Linq; 19 using System.Text; 20 using System.Threading.Tasks; 21 22 namespace ConsoleApplication1.Abstract 23 { 24 interface IState 25 { 26 void Render(); 27 ICommand GetCommand(); 28 } 29 }
先做Statemanager.cs,这个相当于engine,换state并且执行该state的command
View Code
1 using System; 2 using System.Collections.Generic; 3 using System.Linq; 4 using System.Text; 5 using System.Threading.Tasks; 6 using ConsoleApplication1.Abstract; 7 8 namespace ConsoleApplication1 9 { 10 class StateManager 11 { 12 private IState _state; //store current active state 13 14 public void SwitchState(IState state) //switch current state to a new state 15 { 16 _state = state; 17 } 18 19 public void Run(IState initialState) //Run 方法take first state that going to use 20 { 21 _state = initialState; 22 23 while (true) //infinite loop render current state 24 { 25 _state.Render(); 26 var command = _state.GetCommand(); //ask current state's command 27 command.Execute(); //excuted command 28 } 29 } 30 } 31 }
再做第一个MainMenuState