【C#进阶】override new virtual

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

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);
    }

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

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

时间: 2024-11-03 03:45:29

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

浅谈C#中new、override、virtual关键字的区别

OO思想现在已经在软件开发项目中广泛应用,其中最重要的一个特性就是继承,最近偶简单的学习了下在设计模式中涉及到继承这个特性时,所需要用到的关键字,其中有一些关键点,特地整理出来. 一.New 在C#中,new这个关键字使用频率非常高,主要有3个功能: a)   作为运算符用来创建一个对象和调用构造函数. b)   作为修饰符. c)   用于在泛型声明中约束可能用作类型参数的参数的类型. 在本文中,只具体介绍new作为修饰符的作用,在用作修饰符时,new关键字可以在派生类中隐藏基类的方法,也就说

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

OO思想现在已经在软件开发项目中广泛应用,其中最重要的一个特性就是继承,最近偶简单的复习了下在C#中涉及到继承这个特性时,所需要用到的关键字,其中有一些关键点,特地整理出来,方便大家查阅. 一.在C#中,new这个关键字使用频率非常高,主要有3个功能: a)     作为运算符用来创建一个对象和调用构造函数. b)     作为修饰符. c)      用于在泛型声明中约束可能用作类型参数的参数的类型. 在本文中,只具体介绍new作为修饰符的作用,在用作修饰符时,new关键字可以在派生类中隐藏基

c#中抽象类,interface,abstract、override、virtual、sealed使用

interface:接口声明不包括数据成员,只能包含方法,属性,事件,索引等成员,使用接口时不能声明抽象成员(不能直接new实例化) public interface IStringList //接口一般用I作为首字母 { //接口声明不包括数据成员,只能包含方法.属性.事件.索引等成员 //使用接口时不能声明抽象成员(不能直接new实例化) void Add ( string s ) ; int Count{ get; } string this[int index] { get; set;

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

来源:http://blog.csdn.net/jackiezhw/article/details/2673992 在 C# 中,派生类可以包含与基类方法同名的方法. 基类方法必须定义为 virtual. 如果派生类中的方法前面没有 new 或 override 关键字,则编译器将发出警告,该方法将有如存在 new 关键字一样执行操作. 如果派生类中的方法前面带有 new 关键字,则该方法被定义为独立于基类中的方法. 如果派生类中的方法前面带有 override 关键字,则派生类的对象将调用该方

C# 派生,virtual,sealed,new ,override,abstract,base

/*extends,sealed,override,new,virtual,abstract,base * 继承,密闭类,重写(覆盖),隐藏(hide),虚(可替换),抽象,调用父类成员 * 重点:多态性(多种形态polymorphism):相同签名的成员在不同的类中有不同的实现,就被成为多态性,也只同一个签名有多个实现: * 派生/继承:对基类进行特化,包含附加的尘缘或对基类成员进行自定义,建立了“属于”这种关系. * 派生类型/子类型:继承了较常规类型的成员的特化类型 * 基/超/父类型:其

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

C# 语言经过专门设计,以便不同库中的基类与派生类之间的版本控制可以不断向前发展,同时保持向后兼容. 这具有多方面的意义.例如,这意味着在基类中引入与派生类中的某个成员具有相同名称的新成员在 C# 中是完全支持的,不会导致意外行为. 它还意味着类必须显式声明某方法是要重写一个继承方法,还是一个隐藏具有类似名称的继承方法的新方法. 在 C# 中,派生类可以包含与基类方法同名的方法.基类方法必须定义为 virtual.如果派生类中的方法前面没有 new 或 override 关键字,则编译器将发出警

C#中的override和new关键字

问题1: 虚方法 首先,看下面的代码. namespace CSharpTest { class A { public void fun() { Console.WriteLine("这是父类方法"); } } class B : A { public void fun() { Console.WriteLine("这是子类方法"); } } class Test { public static void Main() { A a = new A(); a.fun(

C++11 之 override 关键字

1  公有继承 当派生类公有继承自 (public inheritance) 基类时,继承包含两部分:一是函数的"接口" (interface),二是函数的"实现" (implementation) 基类 Shape 中有三个不同形式的成员函数,分别代表公有继承的三种情况 class Shape { public: virtual void draw() const = 0; virtual void error(const std::string& msg

Delphi之virtual,dynamic,abstract

Delphi之virtual,dynamic,abstract 对象的方法能定义成静态(static).虚拟(virtual).动态(dynamic)或消息处理(message).请看下面 的例子: TFoo = class procedure IAmAStatic; procedure IAmAVirtual; virtual; procedure IAmADynamic; dynamic; procedure IAmAMessage(var M:TMessage); message wm_S