Knowing When to Use Override and New Keywords (C# Programming Guide)
https://msdn.microsoft.com/en-us/library/ms173153.aspx
In C#, a method in a derived class can have the same name as a method in the base class.
You can specify how the methods interact by using the new and override keywords.
The override modifier extends the base class method, and the new modifier hides it.
The difference is illustrated in the examples in this topic.
In a console application, declare the following two classes, BaseClass and DerivedClass.
DerivedClass inherits from BaseClass.
class BaseClass
{
public void Method1()
{
Console.WriteLine("Base - Method1");
}
} class DerivedClass : BaseClass
{
public void Method2()
{
Console.WriteLine("Derived - Method2");
}
}
In the Main method, declare variables bc, dc, and bcdc.
bc is of type BaseClass, and its value is of type BaseClass.
dc is of type DerivedClass, and its value is of type DerivedClass.
bcdc is of type BaseClass, and its value is of type DerivedClass. This is the variable to pay attention to.
Because bc and bcdc have type BaseClass, they can only directly access Method1, unless you use casting.
Variable dc can access both Method1 andMethod2. These relationships are shown in the following code.
class Program
{
static void Main(string[] args)
{
BaseClass bc = new BaseClass();
DerivedClass dc = new DerivedClass();
BaseClass bcdc = new DerivedClass(); bc.Method1();
dc.Method1();
dc.Method2();
bcdc.Method1(); //这个是正常的例子,子类没有重写父类的方法
}
// Output:
// Base - Method1
// Base - Method1
// Derived - Method2
// Base - Method1
}
Next, add the following Method2 method to BaseClass.
The signature of this method matches the signature of the Method2 method in DerivedClass.
public void Method2()
{
Console.WriteLine("Base - Method2");
}
class BaseClass
{
public void Method1()
{
Console.WriteLine("Base - Method1");
}
public void Method2()
{
Console.WriteLine("Base - Method2");
}
} class DerivedClass : BaseClass
{
public void Method2()
{
Console.WriteLine("Derived - Method2");
}
}
父类有Method1和Method2 子类有Method2,并且子类的Method2隐藏了父类的Method2
Because BaseClass now has a Method2 method, a second calling statement can be added for BaseClass variables bc and bcdc, as shown in the following code.
bc.Method1();
bc.Method2();
dc.Method1(); //子类没有Method1,所以调用的是父类的方法
dc.Method2(); //子类有Method2,所以优先调用子类的方法
bcdc.Method1(); //子类没有Method1,所有调用的是父类的方法
bcdc.Method2(); //子类虽然有Method2,但是隐藏了父类Method2,
When you build the project, you see that the addition of the Method2 method in BaseClass causes a warning.
The warning says that the Method2 method in DerivedClass hides the Method2 method in BaseClass.
You are advised to use the new keyword in the Method2 definition if you intend to cause that result.
Alternatively, you could rename one of the Method2 methods to resolve the warning, but that is not always practical.
Before adding new, run the program to see the output produced by the additional calling statements. The following results are displayed.
// Output:
// Base - Method1
// Base - Method2
// Base - Method1
// Derived - Method2
// Base - Method1
// Base - Method2
The new keyword preserves the relationships that produce that output, but it suppresses抑制 the warning.
The variables that have type BaseClass continue to access the members of BaseClass,
and the variable that has type DerivedClass continues to access members in DerivedClass first, and then to consider members inherited from BaseClass.
To suppress the warning, add the new modifier to the definition of Method2 in DerivedClass, as shown in the following code.
The modifier can be added before or after public.
public new void Method2()
{
Console.WriteLine("Derived - Method2");
}
Run the program again to verify that the output has not changed.
Also verify that the warning no longer appears.
By using new, you are asserting断言 that you are aware that the member that it modifies hides a member that is inherited from the base class.
For more information about name hiding through inheritance, see new Modifier (C# Reference).
To contrast对比 this behavior to the effects of using override, add the following method to DerivedClass.
The override modifier can be added before or after public.
public override void Method1()
{
Console.WriteLine("Derived - Method1");
}
Add the virtual modifier to the definition of Method1 in BaseClass. The virtual modifier can be added before or after public.
public virtual void Method1()
{
Console.WriteLine("Base - Method1");
}
Run the project again. Notice especially the last two lines of the following output.
// Output:
// Base - Method1
// Base - Method2
// Derived - Method1
// Derived - Method2
// Derived - Method1
// Base - Method2
The use of the override modifier enables bcdc to access the Method1 method that is defined in DerivedClass.
Typically, that is the desired behavior in inheritance hierarchies.
You want objects that have values that are created from the derived class to use the methods that are defined in the derived class.
You achieve that behavior by using override to extend the base class method.
The following code contains the full example.
The following example illustrates similar behavior in a different context.
The example defines three classes: a base class named Car and two classes that are derived from it, ConvertibleCar有活动折篷的汽车 and Minivan小型货车.
The base class contains a DescribeCar method.
The method displays a basic description of a car, and then calls ShowDetails to provide additional information.
Each of the three classes defines a ShowDetails method.
The new modifier is used to define ShowDetails in the ConvertibleCar class.
The override modifier is used to define ShowDetails in the Minivan class.
// Define the base class, Car. The class defines two methods,
// DescribeCar and ShowDetails. DescribeCar calls ShowDetails, and each derived
// class also defines a ShowDetails method. The example tests which version of
// ShowDetails is selected, the base class method or the derived class method.
class Car
{
public void DescribeCar()
{
System.Console.WriteLine("Four wheels and an engine.");
ShowDetails();
} public virtual void ShowDetails()
{
System.Console.WriteLine("Standard transportation.");
}
} // Define the derived classes. // Class ConvertibleCar uses the new modifier to acknowledge that ShowDetails
// hides the base class method.
class ConvertibleCar : Car
{
public new void ShowDetails()
{
System.Console.WriteLine("A roof that opens up.");
}
} // Class Minivan uses the override modifier to specify that ShowDetails
// extends the base class method.
class Minivan : Car
{
public override void ShowDetails()
{
System.Console.WriteLine("Carries seven people.");
}
}
The example tests which version of ShowDetails is called.
The following method, TestCars1, declares an instance of each class, and then callsDescribeCar on each instance.
public static void TestCars1()
{
System.Console.WriteLine("\nTestCars1");
System.Console.WriteLine("----------"); Car car1 = new Car();
car1.DescribeCar();
System.Console.WriteLine("----------"); // Notice the output from this test case. The new modifier is
// used in the definition of ShowDetails in the ConvertibleCar
// class. ConvertibleCar car2 = new ConvertibleCar();
car2.DescribeCar();
System.Console.WriteLine("----------"); Minivan car3 = new Minivan();
car3.DescribeCar();
System.Console.WriteLine("----------");
}
TestCars1 produces the following output.
Notice especially the results for car2, which probably are not what you expected.
The type of the object isConvertibleCar, but DescribeCar does not access the version of ShowDetails that is defined in the ConvertibleCar class because that method is declared with the new modifier, not the override modifier.
As a result, a ConvertibleCar object displays the same description as a Car object.
Contrast the results for car3, which is a Minivan object.
In this case, the ShowDetails method that is declared in the Minivan class overrides theShowDetails method that is declared in the Car class, and the description that is displayed describes a minivan.
// TestCars1
// ----------
// Four wheels and an engine.
// Standard transportation.
// ----------
// Four wheels and an engine.
// Standard transportation.
// ----------
// Four wheels and an engine.
// Carries seven people.
// ----------
TestCars2 creates a list of objects that have type Car. The values of the objects are instantiated from the Car, ConvertibleCar, and Minivanclasses. DescribeCar is called on each element of the list. The following code shows the definition of TestCars2.
public static void TestCars2()
{
System.Console.WriteLine("\nTestCars2");
System.Console.WriteLine("----------"); var cars = new List<Car> { new Car(), new ConvertibleCar(),
new Minivan() }; foreach (var car in cars)
{
car.DescribeCar();
System.Console.WriteLine("----------");
}
}
The following output is displayed.
Notice that it is the same as the output that is displayed by TestCars1.
The ShowDetails method of the ConvertibleCar class is not called, regardless of whether the type of the object is ConvertibleCar, as in TestCars1, or Car, as in TestCars2.
Conversely相反地, car3 calls the ShowDetails method from the Minivan class in both cases, whether it has type Minivan or type Car.
// TestCars2
// ----------
// Four wheels and an engine.
// Standard transportation.
// ----------
// Four wheels and an engine.
// Standard transportation.
// ----------
// Four wheels and an engine.
// Carries seven people.
// ----------
Methods TestCars3 and TestCars4 complete the example.
These methods call ShowDetails directly, first from objects declared to have typeConvertibleCar and Minivan (TestCars3),
then from objects declared to have type Car (TestCars4).
The following code defines these two methods.
public static void TestCars3()
{
System.Console.WriteLine("\nTestCars3");
System.Console.WriteLine("----------");
ConvertibleCar car2 = new ConvertibleCar();
Minivan car3 = new Minivan();
car2.ShowDetails();
car3.ShowDetails();
} public static void TestCars4()
{
System.Console.WriteLine("\nTestCars4");
System.Console.WriteLine("----------");
Car car2 = new ConvertibleCar();
Car car3 = new Minivan();
car2.ShowDetails();
car3.ShowDetails();
}
The methods produce the following output, which corresponds to the results from the first example in this topic.
// TestCars3
// ----------
// A roof that opens up.
// Carries seven people. // TestCars4
// ----------
// Standard transportation.
// Carries seven people.
The following code shows the complete project and its output.
Knowing When to Use Override and New Keywords (C# Programming Guide)的更多相关文章
- Versioning with the Override and New Keywords (C# Programming Guide)
The C# language is designed so that versioning between base and derived classes in different librari ...
- virtual (C# Reference)
https://msdn.microsoft.com/en-us/library/9fkccyh4.aspx The virtual keyword is used to modify a metho ...
- Polymorphism (C# Programming Guide)
https://msdn.microsoft.com/en-us/library/ms173152.aspx Polymorphism is often referred to as the thir ...
- override (C# Reference)
https://msdn.microsoft.com/en-us/library/ebca9ah3.aspx The override modifier is required to extend o ...
- .NET 面试题: C# override && overloading (C# 覆写 && 重载)
1 1 1 .NET 面试题, C# ,override , overloading, 覆写, 重载,.NET,ASP.NET, override (覆写/重写): 方法名相同,参数的个数和类型相同, ...
- How to Write Doc Comments for the Javadoc Tool
http://www.oracle.com/technetwork/java/javase/documentation/index-137868.html This document describe ...
- Instruments 使用指南
Instruments 用户指南 http://cdn.cocimg.com/bbs/attachment/Fid_6/6_24457_90eabb4ed5b3863.pdf 原著:Apple Inc ...
- Understanding the Objective-C Runtime
Wednesday, January 20, 2010 Understanding the Objective-C Runtime The Objective-C Runtime is one of ...
- SpringBoot+Mybatis配置Pagehelper分页插件实现自动分页
SpringBoot+Mybatis配置Pagehelper分页插件实现自动分页 **SpringBoot+Mybatis使用Pagehelper分页插件自动分页,非常好用,不用在自己去计算和组装了. ...
随机推荐
- CAD得到范围内实体(网页版)
主要用到函数说明: IMxDrawSelectionSet::Select 构造选择集.详细说明如下: 参数 说明 [in] MCAD_McSelect Mode 构造选择集方式 [in] VARIA ...
- 服务器的部署与Web项目的发布
今天给老师的服务器部署项目,这次是第二次,基于第一次的经验,这次可以说是驾轻就熟. 服务器的系统是Windows Server 2008 R2 (64位) 需要安装的软件是:jdk7.TomCat7. ...
- Opencv下双线性插值法进行图像放缩
关于图像放缩的算法有很多,本文主要介绍双线性插值法进行图像放缩,本文参考了: http://www.cnblogs.com/funny-world/p/3162003.html 我们设源图像src的大 ...
- Linux学习笔记(二) 文件管理
了解 Linux 系统基本的文件管理命令可以帮助我们更好的使用 Linux 系统,以下介绍几个常用的文件管理命令 1.pwd pwd 是 Print Working Directory 的简写,用于显 ...
- selenium的调用
selenium的调用 制作人:全心全意 selenium调用谷歌浏览器 chrome = webdriver.Chrome() //创建谷歌浏览器对象 url="http://www.ba ...
- 洛谷 1017 进制转换 (NOIp2000提高组T1)
[题解] 纯模拟题. 我们都知道十进制数化成m进制数可以用短除法,即除m取余.逆序排列.而m进制数化为十进制数,按权展开求和即可. 但在本题中进制的基数R可能为负数,我们知道a%R的符号与R一致,也就 ...
- 【DIP, 图像增强】
第四章 图像增强 图像增强是按特定的需要突出一幅图像中的某些信息,同时削弱或者去除某些不需要的信息的处理方法.其主要目的是使处理后的图像对某种特定的应用来说,比原始图像更加适用.因此这类处理是为了某种 ...
- 网页中添加QQ在线客服
方法一:调用本地已安装的QQ进行会话 <a href='tencent://message/?uin=QQ号码&Site=网站地址&Menu=yes'></a> ...
- 【Codeforces 992B】Nastya Studies Informatics
[链接] 我是链接,点我呀:) [题意] 题意 [题解] 因为gcd(a,b)=x 所以设a = nx b = mx 又有ab/gcd(a,b)=lcm(a,b)=y 则nmx = y 即n(m*x) ...
- nyoj 4 ASCII码排序(set,multiset)
ASCII码排序 时间限制:3000 ms | 内存限制:65535 KB 难度:2 描述 输入三个字符(可以重复)后,按各字符的ASCII码从小到大的顺序输出这三个字符. 输入 第一行输 ...