`
sipgreen
  • 浏览: 25512 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
最近访客 更多访客>>
社区版块
存档分类
最新评论

面向对象编程<继承覆盖>之——C#

阅读更多

 

引用:

C#首席架构师:版本控制、虚拟化和覆盖

网址:http://www.csdn.net/article/2012-09-17/2810048-Anders-Hejlsberg-on-Versioning-Virtual-O

 

 

Bill Venners:在Java中,实例方法默认是虚拟化的,只有显式声明为final时,才可以在子类中被覆盖。相比之下,C#中实例方法默认为非虚拟化,要想声明虚拟化方法需要显式声明它为虚拟的。为什么要这样做?


 

Anders Hejlsberg:原因在于以下几点:

首先是性能。通过观察,我们发现用Java程序员在写代码时常常会忘记将方法声明为final,因此这些方法将是虚拟化的,所以性能并不好。相比于使用虚拟方法这样会带来性能上的提升。这是其一。

更重要的一点在于版本控制。关于虚拟方法主要有两派思想:一是学院派,他们认为“任何事物都应该是虚拟化的,因为我可能会在将来覆盖它”;务实派(从现实世界中获取开发应用的思路)认为“我们只需要关心有必要的虚拟化”。

当我们将平台中某物虚拟化时,对未来的变化做了过多的假设和保留。对于一个非虚拟化的方法,在你调用它时会发生x、y;而在API中发布一个虚拟化的方法时,不仅在你调用该方法时会发生x、y。我们同样保证当你在覆盖这个方法时,会在这个特定的序列中调用它,注意到这些状态不变条件。

每当使用到API中的虚拟化时,你就是在创造一个回调的hook。作为一个OS或者API框架设计师,更需要注意这些。你不会希望用户在API任何部分重载和hook,因为你不一定能保证这些。同样,人们在虚拟化声明某物时也并不一定完全了解他们自己做的保证。

 

 

 

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

在 C# 中,派生类可以包含与基类方法同名的方法。

  • 基类方法必须定义为 virtual。

  • 如果派生类中的方法前面没有 new 或 override 关键字,则编译器将发出警告,该方法将有如存在 new 关键字一样执行操作。

  • 如果派生类中的方法前面带有 new 关键字,则该方法被定义为独立于基类中的方法。

  • 如果派生类中的方法前面带有 override 关键字,则派生类的对象将调用该方法,而不是调用基类方法。

  • 可以从派生类中使用 base 关键字调用基类方法。

  • overridevirtualnew 关键字还可以用于属性、索引器和事件中。

 

new 关键字:

 

 class Father 
    {

        public  int getInt()
        {
            Console.WriteLine("Father:   getInt()");
            return 2;
        }

        public  int setInt()
        {
            Console.WriteLine("Father:   setInt()");
            return 3;
        }

       
    }


//---------------------------------------------------------------------

    class Son : Father
    {

        public new int getInt()
        {
            Console.WriteLine("Son:     getInt()");
            return 1;
        }

    }



//-------------------测试----------------------------------------------------
   class Program
    {
        static void Main(string[] args)
        {
            Father fs = new Son();

            Console.WriteLine(fs.getInt());

            Console.WriteLine(fs.setInt());


            Console.WriteLine("--------------------------------------------------------");

            Son fs2 = new Son();

            Console.WriteLine(fs2.getInt());

            Console.WriteLine(fs2.setInt());

         
            Console.ReadLine();
        }
    }
输出结果:

Father:     getInt()
2
Father:      setInt()
3
----------------------------------------------
Son:     getInt()
1
Father:      setInt()
3

 

Virtural 与 Override 关键字

 

    class Father  {

         public int getInt()
        {
            Console.WriteLine("Father:   getInt()");
            return 2;
        }

        virtual public int setInt()
        {
            Console.WriteLine("Father:   setInt()");
            return 3;
        }

       
    }

 
class Son : Father
    {

        public new int getInt()
        {
            Console.WriteLine("Son:     getInt()");
            return 1;
        }

        public override int setInt()
        {
            Console.WriteLine("Son:     setInt()");
            return 4;
        }

    }

   class Program
    {
        static void Main(string[] args)
        {
            Father fs = new Son();

            Console.WriteLine(fs.getInt());

            Console.WriteLine(fs.setInt());


            Console.WriteLine("--------------------------------------------------------");

            Son fs2 = new Son();

            Console.WriteLine(fs2.getInt());

            Console.WriteLine(fs2.setInt());

             

            Console.ReadLine();
        }
    }

/*
输出结果:

Father:     getInt()
2
Son:      setInt()
4
----------------------------------------------
Son:     getInt()
1
Son:      setInt()
4
*/
 

 

  • 接口中,子类显示实现接口,则为接口调用

  • 隐式实现接口,则为类自己调用

public interface IReview  {
    void GetReviews();  
} 




public class ShopReview :IReview  { 
     public void GetReviews(){}  
}   

//这种方式是隐示实现:   

IReview rv = new ShopReview();rv.GetReviews();   
ShopReview rv = new ShopReview();rv.GetReviews();   

//都可以调用GetReviews这个方法。









//还有一种方式是显示实现:   

public interface IReview  {      
       void GetReviews();  
}  

public class ShopReview :IReview  {  
    void IReview.GetReviews(){}  
}   
//通过这种方式的接口实现。
//GetReviews就只能通过接口来调用:   
IReview rv = new ShopReview();rv.GetReviews();   


//下面的这种方式将会编译错误
ShopReview rv = new ShopReview();rv.GetReviews();   



/*
结论:   
隐示实现接口和类都可以访问   
显示实现只有接口可以访问。   

显示实现益处   
   1:隐藏代码的实现   
    2:在使用接口访问的系统中,调用者只能通过接口调用而不是底层的类来访问。
*/  

 

 

 

 

 

 

 

默认情况下,C# 方法为非虚方法。如果某个方法被声明为虚方法,则继承该方法的任何类都可以实现它自己的版本。若要使方法成为虚方法,必须在基类的方法声明中使用 virtual 修饰符。然后,派生类可以使用 override 关键字重写基虚方法,或使用 new 关键字隐藏基类中的虚方法。如果 override 关键字和 new 关键字均未指定,编译器将发出警告,并且派生类中的方法将隐藏基类中的方法。

分享到:
评论

相关推荐

    c#完全手册中文版

    第七章 表达式&lt;br&gt; 第八章 流程控制&lt;br&gt;第三部分 面向对象的C#&lt;br&gt; 第九章 面向对象的程序设计&lt;br&gt; 第十章 类&lt;br&gt; 第十一章 方法&lt;br&gt; 第十二章 域和属性&lt;br&gt; 第十三章 事件和索引指示器&lt;br&gt; 第十四章 继承&lt;br&gt;第四...

    C#面向对象继承-文件类

    C#面向对象编程基础文件类的PPT文件Path:对文件或目录的路径进行操作(很方便) [字符串] Directory:操作目录(文件夹),静态类 File :操作文件,静态类,对文件整体操作;拷贝,删除,剪切等 Stream:文件流,...

    写给大家看的面向对象编程书(第3版).[美]Matt Weisfeld(带详细书签).pdf

    本书是一部独具特色的面向对象技术著作。书中结合代码示例生动透彻地讲述了面向对象思想的精髓,让读者真正学会以对象方式进行思考。此外,本书还讨论了各种与面向对象概念密切相关的应用主题,包括XML、UML建模语言...

    C#微软培训资料

    第三部分 面向对象的 C#.101 第九章 面向对象的程序设计 .101 9.1 面向对象的基本概念.101 9.2 对象的模型技术 .103 9.3 面向对象的分析 .105 9.4 面向对象的设计 .107 9.5 小 结 .110 第十章 类 .112 ...

    深入C#编程——神奇演示

    里面用到了接口,继承,序列化和反序列化等相关编程知识!

    ASP.NET开发实战1200例(第Ⅰ卷)第三章

    实例073 面向对象编程核心——类、对象和 引用 112 实例074 绘制家谱——用ASP.NET创建类 文件 114 实例075 定制家族权力——设置成员访问的 权限 116 实例076 展现家族——实例化类对象 118 实例077 家族成员——...

    c#学习笔记.txt

    详细介绍请参阅rainbow(一个长着胡子的彩虹)翻译的&lt;&lt;展现C#&gt;&gt; ,前几章非常的有趣。 看完了前面几段,我的朋友提出了不同的意见:C#不是Java的Clone,它只是长得有些像Java而已,其实面向对象、中间语言什么的也...

    测量程序编制 - python A6面向对象-类的多继承.pptx

    面向对象——类的多继承;大部分面向对象的编程语言,都只支持单继承,即子类有且只能有一个父类。而 Python 却支持多继承(C++也支持多继承)。 和单继承相比,多继承容易让代码逻辑复杂、思路混乱,后来的?Java、C#...

    敏捷软件开发原则、模式与实践 C#版

    本书中,享誉全球的面向对象技术大师Robert C. Martin深入而生动地 使用真实案例讲解了面向对象设计的基本原则、重要的设计模式、UML和敏 捷方法。 本书Java版曾荣获2003年第13届Jolt大奖,是公认的经典著作。本书是...

    C# 基础教程

    第三章 面向对象编程的基础知识 21 3.1一切都是“对象” 22 3.1.1 对象和类 24 3.1.2 实例化 25 3.2 面向对象编程语言的三大原则 26 3.2.1 封装 26 3.2.2 继承 28 3.2.3 多态性 30 3.4 本章小结 33 3.5 实战演练 33 ...

    在一小时内学会 C#(txt版本)

    如果你熟悉 C++ 面向对象的方法,你一定对属性有自己的认识。对 C++ 来说,前面例子中 Date 类的属性就是 day、month 和 year,而你添加了 Get 和 Set 方法。C# 提供了一种更加便捷、简单而又直接的属性访问方式。 ...

Global site tag (gtag.js) - Google Analytics