C#中的new和override(转)

 在衍生类中的方法上使用new和override关键字有何意义,可以通过一系列问题来找到答案。先看一段代码:

 1     class Program
 2     {
 3         static void Main(string[] args)
 4         {
 5             Child c = new Child();
 6             c.Func();
 7
 8             Console.Read();
 9         }
10     }
11
12     class Parent
13     {
14         public void Func()
15         {
16             System.Console.WriteLine("parent");
17         }
18     }
19
20     class Child : Parent
21     {
22     }

  问题1: 以上代码中,子类继承父类,所以可以用子类对象调用Func方法,输出字符串为parent。如果在子类中增加与父类相同的方法Func,会出现什么情况?修改子类代码如下,生成代码是成功的,但是有警告,提示子类的Func方法隐藏了父类的Func方法,如果是有意隐藏,请使用关键字new。

1     class Child : Parent
2     {
3         public void Func()
4         {
5             System.Console.WriteLine("Child");
6         }
7     }

这个问题引出了new关键字,但是看来不使用new关键字一样可以隐藏父类的方法,先加上new关键字消除警告,修改子类代码如下,生成成功且无警告,此时输出字符串为Child。

1     class Child : Parent
2     {
3         public new void Func()
4         {
5             System.Console.WriteLine("Child");
6         }
7     }

  问题2:子类对象赋值给子类变量时,new关键字隐藏了父类方法,似乎并没有太重要的意义,并且new关键字都可以省略,那么看一下子类对象赋值给父类变量时,再调用Func方法结果是什么样的?修改入口Main方法如下

1 static void Main(string[] args)
2 {
3     Parent c = new Child();
4     c.Func();
5
6     Console.Read();
7 }

此时输出字符串为parent,并不是输出的Child,那么说明new关键字的隐藏只针对子类对象赋值给子类变量这种情况。

  问题3:那么如何在子类对象赋值给父类变量情况下,根据该变量调用子类实现的Func方法呢?此时就需要用到override关键字,将子类Func方法的new关键字改为override,修改后的子类代码如下

1     class Child : Parent
2     {
3         public override void Func()
4         {
5             System.Console.WriteLine("Child");
6         }
7     }

生成时报错,提示父类的Func方法未标记为 vitual、abstract 或 override,无法进行重写,所以用override重写父类方法的前提是,父类方法必须为虚方法、抽象方法或重写父类的父类方法(重写爷方法...)。现在修改父类Parent的Func为虚方法,代码如下

1 class Parent
2 {
3     public virtual void Func()
4     {
5         System.Console.WriteLine("parent");
6     }
7 }

生成成功,输出字符串为Child,所以从结果来看,似乎override才是真正的“隐藏”父方法。

总结:

(1)将类的对象赋值给该类的变量,则变量调用的必定是该对象的成员,所以new关键字感觉意义不是很大,编译器甚至都允许省略;

(2)将子类对象赋值给父类变量时,使用override重写后,变量调用的是子类方法实现。

时间: 2024-10-24 01:57:14

C#中的new和override(转)的相关文章

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

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

c#中virtual, abstract和override的区别和用法

virtual是把一个方法声明为虚方法,使派生类可重写此方法,一般建立的方法是不能够重写的,譬如类A中有个方法protected void method(){ 原代码....;}类B继承自类A,类B能够调用类A的method()方法,但不能更改方法体代码,但当类A中使用了virtual声明此方法: protected virtual void method(),那么类B可通过使用override重写此方法protected override void method(){ 新代码....;}vir

Android(java)学习笔记148:Eclipse中代码提示去掉@override,不然就报错!

把项目下载下来后有@Override的注释的方法会报错,如果把@Override去掉就不报错了.经过查阅后发现:@override注释在jdk1.5环境下只能用于对继承的父类的方法的重写,但不能用于对实现的接口中的方法的实现,也就是jdk1.5的 @Override 这个annotation 并不把接口认为是超类 ,也就是说 如果在1.5下要使用@Override 这个annotation 必须保证 被标注方法来源于class 而不是interface .具体原因不明,可能是jdk 1.5 的b

C++中的Overload、Override和Overwrite

在C++语言中有一组基础的概念一直都容易混淆:Overload.Override和Overwrite分别表示什么意思?下面把这三个概念整理一下: 1. Overload(重载) 重载的概念最好理解,在同一个类声明范围中,定义了多个名称完全相同.参数(类型或者个数)不相同的函数,就称之为Overload(重载).重载的特征如下: (1)相同的范围(在同一个类中):(2)函数名字相同:(3)参数不同:(4)virtual 关键字可有可无. 2. Override(覆盖) 覆盖的概念其实是用来实现C+

serviceImpl中,方法加@Override注释后报错

@Override public List<SysAdminMenu> getAdminMenusAll() { return sysAdminMenuMapper.getAdminMenusAll(); } 去掉@override注释就不报错,加上就报错,原因是jdk版本太低.解决方法: 选择1.6以上版本,ok,就可以解决问题 原文地址:https://www.cnblogs.com/lc93/p/8418423.html

”static”关键字是什么意思?Java中是否可以覆盖(override)一个private或者是static的方法?

static是表示静态的意思,它可用来修饰成员变量和成员函数,被静态修饰的成员函数只能访问静态成员,不能访问非静态成员.静态是随着类的加载而加载,因此可以直接用类进行访问. 覆盖又称为重写,重写就是子类中的方法和子类继承的父类中的方法一样(函数名.参数类型.参数.返回值类型),但子类的访问权限不要低于父类的访问权限.重写的前提是必须要继承,private修饰不支持继承,因此被私有的方法不能重写.静态的方法形式上是可以被重写的,即子类中可以重写父类中的静态方法,但实际上在内存的角度上静态方法是不可

java中什么叫覆盖Override?请给实例

5.覆盖(Override)  (视频下载) (全部书籍) 马克-to-win:方法的覆盖(Override)是指子类重写从父类继承来的一个同名方法(参数.返回值也同). 例1.5.1---本章源码 class AAAMark_to_win {    double f(double x, double y) {        return x * y;    }} class BBB extends AAAMark_to_win {    double f(double x, double yM

优化ListView中的网络图片加载 及 Volley库源码分析

使用适当的开源库,如Volley或者Universal ImageLoader 以Volley库为例.Volley使用了线程池来作为基础结构,主要分为主线程,cache线程和network线程. 主线程和cache线程都只有一个,而NetworkDispatcher线程可以有多个,这样能解决比并行问题.如下图: 其中左下角是NetworkDispatcher线程,大致步骤是: 1.不断从请求队列中取出请求 request = mQueue.take(); 2.发起网络请求 NetworkResp

23读取联系人移植到项目中

在设置向导的第三个界面,点击"选择联系人按钮"进入选择联系人界面,并且在选择联系人界面传回电话号码到第三个设置向导界面. 监听事件: /** * 选择联系人的按钮的点击事件 * * @param view */ public void selectContact(View view) { Intent intent = new Intent(Setup3Activity.this, SelectContactActivity.class); // 希望返回给本类一个电话号码,所以使用下