你的位置:首页 > ASP.net教程

[ASP.net教程]不要在对抽象类接口abstract virtual什么的混淆不清了


(最近带一个新手入门 讲这边老费力了。)

接口和抽象类不过都是类的抽象罢了,这是他们的本质,只不过人们的思维角度不同而已,一个偏向为行为契约上的抽象(接口) 一个更像大自然中的繁衍关系(抽象类)。

直接上代码:

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  {  }