【C#进阶】override new virtual

时间:2021-09-17 19:24:46

class Organ { public virtual void Intro() { Console.WriteLine("I‘m a organ."); } public string GetOrgan() { return "Cut"; } } class Eye:Organ { public override void Intro() { Console.WriteLine("I‘m an eye"); } public new string GetOrgan() { return "Buy an eye is expensive."; } } class Mouth : Organ { public override void Intro() { Console.WriteLine("I‘m a mouth."); } public string GetOrgan() { return "Buy a mouth is impossible."; } }

 1. NEW 关键字

眼睛和嘴都是器官的子类。

重写了器官类的virtual方法,并且有了自己的实现。

上次面试官问我C#多态怎么体现。我乱答一通。不过我当时说了子类就是父类。现在再补充一下,父类的对象指针可以指向子类的内存空间。

我在main方法里这样调用的。这就是体现了多态。运行时多态。

static void Main(string[] args) { Organ[] organs = { new Mouth(), new Eye(), new Mouth() }; foreach (var or in organs) { or.Intro(); Console.WriteLine("How to get?"); Console.WriteLine(or.GetOrgan()); // cut. Because new hide the method in base class. } var test = new Organ(); test.Intro(); Console.WriteLine("create a derived class object."); var mouth = new Mouth(); Console.WriteLine(mouth.GetOrgan()); }

 (1)new 是子类中同名方法的默认修饰符

其实是默认添加的。你没添加new,但是你有个方法跟基类同名,系统也会默认你加了new。

(2)new 的作用

new的作用:new出来的方法属于派生类,使得父类的指针只能调用自己的这个方法。

我跟面试官说,方法可以new,他偏不信!!!!后来这家公司给我offer了,,我有点冲动,想当面告诉他,C#里方法是可以添加new 修饰符的!

方法表  (面试时候,要提到类型指针,override,在运行时决定,记得想象类型指针和方法表,答多态的时候。可以不要提new 关键字,因为有些面试官确实不知道这个知识点)

---------------

Mouth 方法表:

override void Intro()  <------- 只有带override关键字的方法父类才可见,

new string GetOrgan()    ///////其余的new的方法,父类对象是看不到的

---------------------

Organ 方法表:

virtual void Intro()

string GetOrgan()  <-------- 这个方法,父类指针就执行自己的。

--------------------

\

\\\\\

\...直到object的方法表

一旦这类型指针是Organ,只会向终极object查找,而不会回头再去Mouth方法表里找。

当时面试官跟我强调:动态绑定。我是不太理解的。现在的想法是,类型指针是在运行时决定的

Organ organs = {

new Mouth(),

new Eye()}

我们写程序想用上多态,一般都是使用父类对象指向子类。

Organ organ = new Mouth()。在堆里创建一个子类对象。

2. Virtual虚方法实现多态 关键字 base:virtual;derived:override

3. Abstract抽象方法实现多态 base: abstract;derived:override

选2还是3?取决于我们是否需要使用基类实例化的对象。

抽象类就不能创建实例对象,你不需要基类实例化的时候,(person,teacher,student例子)

而有虚方法的基类,会有普通的基类实例(Employee,projectmanager,accountants例子)就举这两个例子

4.Interface接口实现多态

”里氏替换原则(Liskov Substitution Principle):派生类(子类)对象能够替换其基类(超类)对象被使用。通俗一点的理解就是“子类是父类”,举个例子,“男人是人,人不一定是男人”,当需要一个父类类型的对象的时候可以给一个子类类型的对象;当需要一个子类类型对象的时候给一个父类类型对象是不可以的!