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."; }
}

最新总结

对于父类引用来说,即蔬菜=new 胡萝卜()

鸡肋引用= new 派生类()

****Condition 1:派生类override 去修饰某个同名鸡肋方法

鸡肋引用.那个鸡肋方法名,此时调用的是派生类中方法;

****Condition 2:派生类new/ 啥没写 去修饰某个同名鸡肋方法 

鸡肋引用.那个鸡肋方法名,此时调用的是鸡肋中方法。

对condition 2 中的情况,鸡肋引用看这个方法是个虚的,看看派生类有木有实现呀?答案是yes,可以你new了,这个方法是属于派生类本身的,我还是用我自己的鸡肋方法~

对于派生类引用,即胡萝卜 小胡=new 胡萝卜()

胡萝卜:蔬菜

也就是自己就是自己的引用

****Condition 1:派生类override 去修饰某个同名鸡肋方法

小胡.那个鸡肋方法名,此时调用的是派生类中方法;

****Condition 2:派生类new/ 啥没写 去修饰某个同名鸡肋方法 

小胡.那个鸡肋方法名, 此时调用的是派生类中方法;

对小胡来说,执行的都是自己的

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()。在堆里创建一个子类对象。

http://www.cnblogs.com/longteng1991/archive/2013/06/13/3131739.html

http://blog.jobbole.com/102091/

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):派生类(子类)对象能够替换其基类(超类)对象被使用。通俗一点的理解就是“子类是父类”,举个例子,“男人是人,人不一定是男人”,当需要一个父类类型的对象的时候可以给一个子类类型的对象;当需要一个子类类型对象的时候给一个父类类型对象是不可以的!

开放封闭原则(Open Closed Principle):封装变化、降低耦合,软件实体应该是可扩展,而不可修改的。也就是说,对扩展是开放的,而对修改是封闭的。因此,开放封闭原则主要体现在两个方面:对扩展开放,意味着有新的需求或变化时,可以对现有代码进行扩展,以适应新的情况。对修改封闭,意味着类一旦设计完成,就可以独立完成其工作,而不要对类进行任何修改。“摘抄自http://www.cnblogs.com/longteng1991/archive/2013/06/13/3131739.html

接口的设计体现着一种功能~ 比如这文章提到的飞,什么类实现了这个飞的接口,就有了飞的功能。这飞的东西,可以是某种鸟儿,可以是飞机。有点明白接口了。写个例子试试看。让我想一想,除了飞,还有哪些功能。。。

猫和人都可以说话 实现ITalkable接口。

            ITalkable[] t = { new Chinese(),new American(),new Chinese(),new Cat() };
foreach (var staff in t) {
staff.Speak("People's Saying.");
}
Person[] pts= { new Chinese(), new American() };
foreach(var per in pts)
{
per.Introduce();
}
猫还是说猫话,尽管传的是人的话。

class Cat : ITalkable
{
public void Speak(string language)
{
Console.WriteLine("I CAN SPEAK cat language.");
}
}
abstract class Person
{
public string Country;
public abstract void Introduce();
}
class Chinese : Person,ITalkable
{
public Chinese()
{
this.Country = "China";
}
public void Speak(string language)
{
Console.WriteLine("I CAN SPEAK {0}",language);
}
public override void Introduce()
{
Console.WriteLine("Country is {0}.", Country);
this.Speak("Chinese");
}
}
class American : Person, ITalkable
{
public American()
{
this.Country = "America";
}
public void Speak(string language)
{
Console.WriteLine("I CAN SPEAK {0}", language);
}
public override void Introduce()
{
Console.WriteLine("Country is {0}.", this, Country);
this.Speak("English");
}
}

接口定义:

    interface ITalkable
{
void Speak(string language);
}

我代码写得很烂,虽然如此,我还写,你们还有什么理由不写代码??

这文章自己看的,希望没有误导别人,本人水平有限,菜鸟大神绕道。

【C#进阶】override new virtual的更多相关文章

  1. 浅析C#中new、override、virtual关键字的区别

    Virtual : virtual 关键字用于修饰方法.属性.索引器或事件声明,并使它们可以在派生类中被重写. 默认情况下,方法是非虚拟的.不能重写非虚方法. virtual 修饰符不能与 stati ...

  2. 【C#】override,Abstract,Virtual 介绍及区别--转载

    要扩展或修改继承的方法.属性.索引器或事件的抽象实现或虚实现,必须使用 override 修饰符. 1. override 方法提供从基类继承的成员的新实现.通过 override 声明重写的方法称为 ...

  3. Delphi 方法:overload、override、virtual、dynamic、abstract

    1.overload 在Pascal语法规则中,同一个UNIT里是不能存在两个同名的函数的,例如: function func(): Boolean; function func(const x: C ...

  4. 转: Delphi的OverRide、OverLoad和Virtual方法

    http://blog.csdn.net/ckli/article/details/2201418 override 重写 也叫覆盖 .方法的重写Overriding和重载Overloading是Ja ...

  5. C#中的Virtual、Override和new关键词理解

    来源:http://blog.csdn.net/jackiezhw/article/details/2673992 在 C# 中,派生类可以包含与基类方法同名的方法. 基类方法必须定义为 virtua ...

  6. Delphi之静态方法,虚方法virtual,动态dynamic,抽象abstract,消息

    Delphi之静态方法,虚方法virtual,动态dynamic,抽象abstract,消息 http://www.cnblogs.com/zhwx/archive/2012/08/28/266055 ...

  7. C++11 之 override

    1  公有继承 派生类公有继承自 (public inheritance) 基类,继承包含两部分:一是函数的 "接口" (interface),二是函数的 "实现&quo ...

  8. abstract virtaul override new 及多态

    abstract abstract 修饰符可以和类.方法.属性.索引器及事件一起使用.在类声明中使用 abstract 修饰符以指示某个类只能是其他类的基类.标记为抽象或包含在抽象类中的成员必须通过从 ...

  9. 使用 Override 和 New 关键字进行版本控制

    使用 Override 和 New 关键字进行版本控制 C# 语言经过专门设计,以便不同库中的基类与派生类之间的版本控制可以不断向前发展,同时保持向后兼容. 这具有多方面的意义.例如,这意味着在基类中 ...

随机推荐

  1. appium依赖pom文件注解

    <!-- appium部分 依赖--> <dependency> <groupId>io.appium</groupId> <artifactId ...

  2. activity 、window与view的关系(下)

    在activity的attacth方法中,通过policymanager 的makenewwindow来创建window 而window的具体实现是phonewindow 接下来通过setconten ...

  3. 在android studio 中使用applicationid的问题

    现在我需要对项目app的某个功能做性能测试,主要测试耗电量的多少. 1.我想到的方式是,我需要在同一台手机测试,同一个应用,需要安装在手机两次,第二次安装不覆盖第一次的安装. 在android stu ...

  4. Linux CentOS6.5下安装Oracle ASM

    Oracle版本:Oracle 11g 1.确定自己的Linux版本: [root@localhost ~]#uname -r 2.6.32-431.el6.x86_64 2.6.32-431.el6 ...

  5. Linux用户密码重置方法

    方法一: 启动时,随便按一个键,空格即可(不能是回车),让其停留在如下界面 按e编辑 在UTF-8后面添加init=/bin/sh init=/bin/sh 根据上面提示,按Ctrl+x启动得下图 输 ...

  6. C# Questions

    What's the difference between linkedlist and array? How do you implement linkedlist? What's the diff ...

  7. HashSet

  8. Entity Framework 基于方法的查询语法

      实体框架(Entity Framework )是 ADO.NET 中的一套支持开发面向数据的软件应用程序的技术. LINQ to Entities 提供语言集成查询 (LINQ) 支持,它允许开发 ...

  9. 【iCore3 双核心板_FPGA】实验二十八:基于SDRAM 的VGA 驱动器的设计

    本实验设计的VGA显示驱动完全基于FPGA实现,用SDRAM做缓存设备,通过ARM控制VGA显示的内容.ARM 通过FSMC总线向FPGA发送数据,由于总线的速度和VGA的显示速度与SDRAM的读写速 ...

  10. 前端开发自学之JavaScript——显示当前时间

    <html> <head> <title>JavaScript</title> <script language="javascript ...