C#和Java的类、继承、重写与多态

摘要:
面向对象的三个特点是封装、继承和多态性。C#和Java是面向对象的语言,因此它们的类、继承、重写和多态性有很多共同点,但在实现上也存在一些差异。新的SayHi()在子类中隐藏父类的SayHi(),因此obj2的输出是:“HiDerived”。可以看出,隐藏与多态性无关。override和new的区别在于override应该与virtual一起使用,而new不需要使用virtual/override来实现多态性。相反,new总结了Java的重写和多态性在语法上比C#的实现更简单,关键字更少,语法也没有那么复杂。

面向对象的三大特性是封装、继承、多态,C#和Java都是面向对象的语言所以他们的类、继承、重写与多态有很多共同点,但是实现上也存在一定的区别。其中Java中其实没有虚函数的概念,也可以认为Java的函数默认都是虚函数都可以被重写;而在C#中要用关键字virtual指明特定的函数为虚函数才可以实现重写。

多态

多态的意思的一个接口或对象的变量在运行时可以有多种不同的形态,这是通过运行时绑定(晚绑定)实现的。

一个接口或对象的变量在运行时可以动态地指向多个对象中的一个,所以多态的结果是直到运行的那一刻才知道具体执行的是哪个对象的方法。

通过继承接口实现多态

假如有一个接口A,A中有一个方法SayHi(),然后B和C实现了接口A,关系如下:

A <- B

A <- C

接口的多态:

  1. 声明一个接口A的变量:A a = null;
  2. 在运行的过程中动态地给a赋予B或C的对象
  3. 调用A的SayHi()方法,这时实现了动态地调用B或C的SayHi()

通过重写方法实现多态

重写指的是在继承的关系中,子类重写(override)了父类的相同签名的方法(相同方法名并且相同的参数)。

假如有一个类A,A中有一个虚函数(virtual)SayHi(),然后B和C继承了类A,并都重写了父类A的方法SayHi()关系如下:

A <- B

A <- C

重写的多态:

  1. 声明一个父类A的变量:A a = null;
  2. 在运行的过程中动态地给a赋予B或C的对象
  3. 调用a的SayHi()方法,这时实现了动态地调用B或C的SayHi()

 

C#中的重写

C#的重写必须使用关键字virtual和override,其中virtual用于父类的方法,指明该方法为虚函数,override用于子类的相应方法,指明该方法重写父类的方法。

class Program
{
    static void Main(string[] args)
    {
        BaseClass obj = new DerivedClass();
        obj.SayHi();
        Console.ReadKey();
    }

    class BaseClass
    {
        public virtual void SayHi()
        {
            Console.WriteLine("Hi Base.");
        }
    }

    class DerivedClass : BaseClass
    {
        public override  void SayHi()
        {
            Console.WriteLine("Hi Derived.");
        }
    }  
}

输出:

Hi Derived.

 

Java中的重写

java默认所有的方法都是虚函数(可以通过final关键字把方法声明为非虚函数),默认都可以被重写,所以java的重写要比C#简单一些:

public class Example {
    public static void main(String[] args) {
        BaseClass base = new DerivedClass();
        base.SayHi();
    }
}

class BaseClass {
    public void sayHi() {
        System.out.println("Hi Base.");
    }
}

class DerivedClass extends BaseClass {
    public void sayHi() {
        System.out.println("Hi Derived.");
    }
}

输出:

Hi Derived.

C#特有的new修饰符

C#的new修饰符的作用有点难以理解,官方定义是用于隐藏父类具有同签名的方法,隐藏是针对子类的,可以简单理解为:

声明一个和父类具有同样签名的方法并告诉编译器我这个方法和父类的方法没有任何联系。

单单从定义看很难理解它的真正含义,用代码来说话:

class Program
{
    static void Main(string[] args)
    {
        BaseClass obj1 = new DerivedClass();
        obj1.SayHi();

        DerivedClass obj2 = new DerivedClass();
        obj2.SayHi();

        Console.ReadKey();
    }

    class BaseClass
    {
        public void SayHi()
        {
            Console.WriteLine("Hi Base.");
        }
    }

    class DerivedClass : BaseClass
    {
        public new void SayHi()
        {
            Console.WriteLine("Hi Derived.");
        }
    }  
}

输出:

Hi Base.
Hi Derived.

由运行结果可以看出来,obj1变量虽然在运行的过程中被赋予了DerivedClass对象,但是在调用SayHi()的时候实际是是调用了BaseClass的SayHi()。

结果分析:

  1. 因为new修饰的方法只是隐藏,SayHi()没有被重载,所以obj1的输出是:"Hi Base.",注意这是new修饰词的一个不好理解的坑。
  2. 在子类中用新的SayHi()隐藏了父类的SayHi(),所以obj2的输出是:"Hi Derived."

由此可见:

隐藏与多态无关

override和new的区别:

  • override要和virtual配合使用,而new并不需要(new也可以隐藏非虚函数)
  • 用virtual/override是为了实现多态,而new恰好相反

总结

从语法上看Java的重写与多态在实现上要比C#简洁一些,没有那么多的关键字,也没有那么多复杂难懂的语法。但是C#比Java多了一个特性就是子类可以拥有一个和父类具有同样签名的新方法,费那么多力气去换一个也不是太常用的特性是不是有点不值得呢。

转载请注明出处:http://www.cnblogs.com/keitsi/p/6137605.html

免责声明:文章转载自《C#和Java的类、继承、重写与多态》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇深入理解Spring Redis的使用 (一)、Spring Redis基本使用java--jvm启动的参数下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

C++面试

https://blog.csdn.net/weixin_44363885/article/details/99567746 这一行是个 贼鸡巴重要的链接!!!   很好的总结 我直接复制到下面了: 社招:社招的同学,无论是1-3年经验,还是中途转行,都可参考。写简历必须有针对性,以后台开发为例,请去拉勾网 / 猎聘 / 智联招聘等网站,多看看后台开发的J...

UVM中的class--2

1)uvm_component从uvm_report_object继承而来,提供的功能包括: 1)Hierarchy,-----searching and traversing component hierachy 2)Phasing-----调用uvm_phase以及预先定义的很多phase 3)config-------调用config_db的m...

11-c++虚拟函数

虚拟函数 #include "stdio.h" class A{   public:     void print()     {       printf("%s","this is A ");     } }; class B:public A{   public:     void print()     {       printf("%s","...

如何在windows xp下实现声音内录

问题描述: 用屏幕录制软件录制一个视频,能够成功录制视频,但无法录制视频里面的声音。 问题原因: 因为现在的多数声卡,均无法直接通过声卡自身的功能实现内录和立体声混音。 这是由于声卡芯片厂商迫于RIAA(Recording Industry Association ofAmerica,美国唱片工业联合会)的压力,及维护音乐版权防止内录的需要,在新推出的声卡...

C++ 系列:虚函数

Copyright © 1900-2016, NORYES, All Rights Reserved. http://www.cnblogs.com/noryes/ 欢迎转载,请保留此版权声明。 ---------------------------------------------------------------------------------...

html中#include file的使用方法

有两个文件a.htm和b.htm,在同一文件夹下a.htm内容例如以下 <!-- #include file="b.htm" --> b.htm内容例如以下 今天:雨 31 ℃~26 ℃ <br />明天:雷阵雨 33 ℃~27 ℃ 直接在浏览器中打开a,没有不论什么显示,后来知道,include是SSI(Server Side...