·您现在的位置: 云翼网络 >> 文章中心 >> 网站建设 >> 网站建设开发 >> ASP.NET网站开发 >> 不要在对抽象类接口abstract virtual什么的混淆不清了

不要在对抽象类接口abstract virtual什么的混淆不清了

作者:佚名      ASP.NET网站开发编辑:admin      更新时间:2022-07-23

不要在对抽象类接口abstract virtual什么的混淆不清了

2015-04-15 07:36 by JasonShenW, ... 阅读, ... 评论, 收藏, 编辑

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

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

直接上代码:

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