扩展方法实现对接口扩展
在使用面向对象的语言进行项目开发的过程中,我们会较多的会使用到定义接口、继承等方式,来减少常用的操作。但是并非所有的场景都适合使用“继承”特性。
继承带来的问题,对象的继承关系在运行时就已经定义好了,子类的实现与它父类有非常紧密的依赖关系,以至于在修改父类的情况下,会影响到相关继承父类的子类。
c#3.0扩展方法
- 扩展方法被定义为静态方法,但它们是通过实例方法语法进行调用的
- 必须携带一个参数,参数指定该方法作用于哪个类型,并且该参数以 this 修饰符为前缀
- 只能是访问所扩展类的public成员
实例
1 /*定义组装汽车*/ 2 interface ICar 3 { 4 //定义车身 5 string Frame(); 6 //定义车灯 7 string CarLight(); 8 //定义座椅 9 string Chair(); 10 //定义轮子 11 string Wheel(); 12 //定义方向盘 13 string SteeringWheel(); 14 }
1 public class Benz : ICar 2 { 3 /*继承父类*/ 4 public string CarLight() 5 { 6 return "安装奔驰车灯"; 7 } 8 9 public string Chair() 10 { 11 return "安装奔驰座椅"; 12 } 13 14 public string Frame() 15 { 16 return "设计车身结构"; 17 } 18 19 public string SteeringWheel() 20 { 21 return "安装奔驰方向盘"; 22 } 23 24 public string Wheel() 25 { 26 return "安装奔驰轮子"; 27 } 28 }
1 public class Ferrari : ICar 2 { 3 /*继承父类*/ 4 public string CarLight() 5 { 6 return "安装法拉利车灯"; 7 } 8 9 public string Chair() 10 { 11 return "安装法拉利座椅"; 12 } 13 14 public string Frame() 15 { 16 return "设计车身结构"; 17 } 18 19 public string SteeringWheel() 20 { 21 return "安装法拉利方向盘"; 22 } 23 24 public string Wheel() 25 { 26 return "安装法拉利轮子"; 27 } 28 }
调用例子
1 private void btnBenz_Click(object sender, EventArgs e) 2 { 3 ICar benz = new Benz(); 4 listBox1.Items.Add("工人1号正在安装奔驰!"); 5 listBox1.Items.Add(benz.Frame()); 6 listBox1.Items.Add(benz.Wheel()); 7 listBox1.Items.Add(benz.SteeringWheel()); 8 listBox1.Items.Add(benz.Chair()); 9 listBox1.Items.Add(benz.CarLight()); 10 } 11 12 private void btnFerrari_Click(object sender, EventArgs e) 13 { 14 ICar ferrari = new Ferrari(); 15 listBox1.Items.Add("工人2号号正在安装法拉利!"); 16 listBox1.Items.Add(ferrari.Frame()); 17 listBox1.Items.Add(ferrari.Wheel()); 18 listBox1.Items.Add(ferrari.SteeringWheel()); 19 listBox1.Items.Add(ferrari.Chair()); 20 listBox1.Items.Add(ferrari.CarLight()); 21 }
以上完成一个简单的子类继承父类,实现父类定义的接口方法
现在我新安装一辆大众CC,并需要加装一个天窗,这时候我们就需要调整父类,添加天窗的接口定义
1 /*定义组装汽车*/ 2 interface ICar 3 { 4 //定义车身 5 string Frame(); 6 //定义车灯 7 string CarLight(); 8 //定义座椅 9 string Chair(); 10 //定义轮子 11 string Wheel(); 12 //定义方向盘 13 string SteeringWheel(); 14 15 /*定义新接口,添加天窗*/ 16 string SkyLight(); 17 }
这样就会产生以下问题,由于我们的Benz和Ferrari不需要天窗,但是又在父类定义了天窗的接口,从而导致Benz和Ferrari,都需要实现天窗的接口,明显不符合客户需求,应该怎么办?
这时候我们可以是要扩展方法,结合上列扩展方法的概述,我们对结构进行调整
安装大众CC
1 public class VolkswagenCC : ICar 2 { 3 /*继承父类*/ 4 public string CarLight() 5 { 6 return "安装大众CC车灯"; 7 } 8 9 public string Chair() 10 { 11 return "安装大众CC座椅"; 12 } 13 14 public string Frame() 15 { 16 return "设计车身结构"; 17 } 18 19 public string SteeringWheel() 20 { 21 return "安装大众CC方向盘"; 22 } 23 24 public string Wheel() 25 { 26 return "安装大众CC轮子"; 27 } 28 }
扩展大众CC天窗方法
1 public static class CCExtend 2 { 3 public static string SkyLight(this ICar ii) 4 { 5 return "安装大众CC天窗"; 6 } 7 }
完成大众CC天窗安装
1 private void btnCC_Click(object sender, EventArgs e) 2 { 3 ICar CC = new VolkswagenCC(); 4 listBox1.Items.Add("工人3号正在安装法拉利!"); 5 listBox1.Items.Add(CC.Frame()); 6 listBox1.Items.Add(CC.Wheel()); 7 listBox1.Items.Add(CC.SteeringWheel()); 8 listBox1.Items.Add(CC.Chair()); 9 listBox1.Items.Add(CC.CarLight()); 10 listBox1.Items.Add(CC.SkyLight()); 11 }