不要在对抽象类接口abstract virtual什么的混淆不清了
2015-04-15 07:36 FelixShen 阅读(951) 评论(0) 编辑 收藏 举报(最近带一个新手入门 讲这边老费力了。)
接口和抽象类不过都是类的抽象罢了,这是他们的本质,只不过人们的思维角度不同而已,一个偏向为行为契约上的抽象(接口) 一个更像大自然中的繁衍关系(抽象类)。
直接上代码:
class 抽象类 { public static void Main(string[] args) { ChinesePerson c = new ChinesePerson("xx", 23); c.Run(); c.Speak(); Console.WriteLine(c.Name); Console.WriteLine(c.Age); Console.WriteLine(c.Hobby); Console.WriteLine("--------"); c.fight(); JiangSuPerson j = new JiangSuPerson(); j.Name = "xiaomao"; j.Age = 24; j.Run(); j.Speak(); j.fight(); j.sing(); Console.WriteLine(j.Name); Console.WriteLine(j.Age); Console.WriteLine(j.Hobby); Console.WriteLine("----------"); HenanPerson h = new HenanPerson(); h.Name = "linyi"; h.Speak(); h.fight(); h.sing(); Console.ReadKey(); } } public interface IRun { void Run(); } public abstract class Person : IRun { private string name; private int age; public string Name { get { return name; } set { name = value; } } public int Age { get { return age; } set { age = value; } } public abstract string Hobby { get; set; } public Person(string name, int age) { this.Name = name; this.Age = age; } public Person() { } public abstract void Speak(); public void Run() { Console.WriteLine("Running ~~"); } //能够被子类重写的 只有 abstract 或virtual修饰的, //不同在于,abstract一定要被重写,而virtual则是可以被重写 但不一定非要重写,还有就是virtual要有方法体。 public virtual void fight() { Console.WriteLine("fighting"); } } public class ChinesePerson : Person { public ChinesePerson(string name, int age) : base(name, age) { this.Name = name; this.Age = age; } public ChinesePerson() { } public override void Speak() { Console.WriteLine("中国人说中文"); } public override string Hobby { get { return "shopping"; } set { } } public override void fight() { base.fight(); Console.WriteLine("chinese gongfu fighting"); } public virtual void sing() { Console.WriteLine("用中文唱歌"); } } //继承自中国人,但是没有任何重写 public class JiangSuPerson : ChinesePerson { } public class HenanPerson : ChinesePerson { public override void Speak() { Console.WriteLine("河南人说河南方言"); } public override void sing() { Console.WriteLine("用河南话唱歌"); } }
总结一下:抽象类 和接口都是类的抽象,接口更关注从行为方面来抽象,而在语法上 接口的内容必须都是没有实现的,完全等待后面的类来实现的
而在这一点上,抽象类则像是一个没有完全实现的类,他想所有普通类一样,可以拥有字段,属性,以及方法,这些都是可以有具体实现体的,
但就这样的话,他和普通类的差别只在于他不可以通过new实例化,而他的真正不同在于 他应该有abstract修饰的部分,这部分没有具体实现,必须由
由后面的实现类来具体实现。
而virtual关键字本不该属于这里的讨论范畴,他修饰的方法和普通方法几乎一样,都是有着方法体的,但是被virtual修饰的可以被子类重写。
再举个例子模拟下mvc的控制器模块
//大致模拟了MVC框架中的控制器模块的思想 class 抽象类二 { public static void Main(string[] args) { IController ic; ic = new HomeController(); ic.Execute(); Console.ReadKey(); } } public interface IController { void Execute(); } public abstract class ControllerBase : IController { //可以选择性的重写这整个方法,而不按照所期望的分步骤 public virtual void Execute() { Console.WriteLine("doing some unimporting things"); ExecuteCore(); } //这个方法则必须实现 public abstract void ExecuteCore(); } public abstract class Controller : ControllerBase { public override void ExecuteCore() { Console.WriteLine("doing some importing things"); } //public override void Execute() //{ // Console.WriteLine("doing the whole things"); //} } public class HomeController : Controller { }
如果你喜欢~就请推荐一下吧O(∩_∩)O