以继承为基础,继承举例:

public class Person
{
 public void Sayhello()
 {
  Console.WriteLine("Hello,I am a person");
 }
}
public class Student:Person
{
}

Student类继承与Person类

我们想改变Student里面继承Person的SayHello()方法,使其具有自己的特性.这里使用new关键字.

public class Person
{
 public void SayHello()
 {
  Console.WriteLine("Hello,I am a person");
 }
}
public class Student:Person
{
 new public void SayHello()
 {
  Console.WriteLine("hello,I am a student");
 }
}

public class Test
{
 static void Main()
 {
  Person aPerson=new Person();
  Student aStudent = new aStudent();
  
  aPerson.SayHello();
  aStudent.SayHello();
 }
}

输出:
hello,I am a person
hello,I am a student

这个过程在Inside C#-MSPress称为override:
you want to derive a class from (Person) and you want to override the (SayHello) method to do something specific to the derived class. To do this, you need to use the new keyword with the derived class's method definition.
但在翻译成中文时,称为:隐藏.

多态(Polymorphism)

当使用关键字new来override基类的方法时,程序运行很尽人意.
(Method overriding with the new keyword works fine if you have a reference to the derived object)

语言的每个概念的产生都是需要理由的(你不防问问自己为什么c#会有Class,Method...这些概念),这里,我们要问:
为什么会有多态这个概念的出现?有什么用处呢?
(看了很多.NET书籍,好像没有这样来解释各个概念的)

从实际出发,看下面例子:Student,Teacher都是Person,在实际应用中,我们需要把所有Person的派生类组装(populate)到一个数组里面,这个数组的数据类型必定是Person了,而且,通过这个Person[]数组来重新调用数组元素(Person的派生类)的SayHello方法.

public class Person
{
 public void SayHello()
 {
  Console.WriteLine("Hello,I am a person");
 }
}
public class Student:Person
{
 new public void SayHello()
 {
  Console.WriteLine("hello,I am a student");
 }
}
public class Teacher:Person
{
 new public void SayHello()
 {
  Console.WriteLine("hello,I am a teacher");
 }
}
public class Test
{
 private static Person[] persons=new Person[2];
 static void Main()
 {
  persons[0]=new Student();
  persons[1]=new Teacher();
 
  persons[0].SayHello();
  persons[1].SayHello();
 }
}

输入结果:
hello,I am a person
hello,I am a person

(Obviously, this is not what we wanted)对,在实际应用中,我们不希望出现这种结果.
希望输出:
hello,I am a student
hello,I am a teacher

上面的例子,为什么会出现我们所不希望的结果呢?
看看Inside C#的解释:

What happened here is an example of a phenomenon called early binding. When the code was compiled, the C# compiler looked at the call to Persons[].SayHello() and determined the address in memory that it would need to jump to when the call is made. In this case, that would be the memory location of the Person.SayHello method.
Take a look at the following MSIL that was generated from the Test application, and specifically take note of line IL_0014 and the fact that it explicitly calls the Employee.CalculatePay method:

....
IL_0014:  call       instance void Employee::CalculatePay()

....

That call to the (Person.SayHello) method is the problem. What we want instead is for late binding to occur. Late binding means that the compiler does not select the method to execute until run time. To force the compiler to call the correct version of an upcasted object's method, we use two new keywords: virtual and override. The virtual keyword must be used on the base class's method, and the override keyword is used on the derived class's implementation of the method.

public class Person
{
 virtual public void SayHello()
 {
  Console.WriteLine("Hello,I am a person");
 }
}
public class Student:Person
{
 override public void SayHello()
 {
  Console.WriteLine("hello,I am a student");
 }
}
public class Teacher:Person
{
 override public void SayHello()
 {
  Console.WriteLine("hello,I am a teacher");
 }
}
public class Test
{
 private static Person[] persons=new Person[2];
 static void Main()
 {
  persons[0]=new Student();
  persons[1]=new Teacher();
 
  persons[0].SayHello();
  persons[1].SayHello();
 }
}

Before running this application, let's take a peek at the IL code that's generated, this time noting that line IL_0014 uses the MSIL opcode callvirt,which tells the compiler that the exact method to be called won't be known until run time because it's dependent on which derived object is being used:

.....
IL_0014:  callvirt   instance void Employee::CalculatePay()
.....

输出为:
hello,I am a student
hello,I am a teacher

要深刻理解这个过程,必须搞明白什么是"Early Binding&Late Binding","run time",具有"编译原理"相关知识.
本人还没有学习"编译原理"以及"汇编程序",这一点还是没有搞彻底,不再引用这方面的资料,可以查阅MSDN

BTW,我们还可以用类型转换来得到我们想要的:
class Test修改为:

public class Test
{
 private static Person[] persons=new Person[2];
 static void Main()
 {
  persons[0]=new Student();
  persons[1]=new Teacher();
 
  Student s=new Student();
  Teacher t=new Teacher();

  s=(Student)persons[0];
  t=(Teacher)Persons[1];

  s.SayHello();
  t.SayHello();

 }
}

===========================================
以上文章参考(部分字句为直接翻译)
[1]Inside C# / Tom Archer.(Microsoft Press)
[2]Visual C# .NET:A Gudie for VB6 Develops/Brand Maiani,James Still...(Wrax)

转载于:https://www.cnblogs.com/caca/archive/2004/07/27/27842.html

C#学习笔记:多态与隐藏,覆盖相关推荐

  1. java多态怎么学_Java学习笔记---多态

    在面向对象的程序设计中,多态是继数据抽象和继承之后的第三种基本特性: 多态通过分离做什么(基类对象)和怎么做(导出类对象),从另一角度将接口和实现分离开来.多态不但能够改善代码的组织结构和可读性,还能 ...

  2. SV学习笔记—多态与类型转换

    0.前言 当同一操作作用于不同对象,能有不同的解释从而产生不同的结果,这就叫做多态,多态在验证中被大量使用 多态的实现基础是什么? 1.多态的实现基础是继承,没有继承就没有多态 2.多态通过子类覆盖父 ...

  3. C++学习笔记——多态

    前面说到了继承,那么就衍生出了多态. 目录 概念 实现 1.前提 2.虚函数 3.重写 4.示例 4.抽象类 原理 1.虚表指针 2.虚表 多继承和单继承的虚函数表 1.多继承的虚表指针 2.菱形继承 ...

  4. Java学习笔记-多态的具体体现

    面向对象编程有四个特征:抽象.封装.继承.多态. 多态有四种体现形式:1.接口和接口的继承2.类和类的继承3.重载4.重写其中重载和重写是核心.# 重载:重载发生在同一类中,在该类中如果存在多个同名方 ...

  5. 【b站黑马程序员C++视频学习笔记-多态案例三-电脑组装】

    多态案例三-电脑组装 电脑主要组成部件为CPU(用于计算),显卡(用于显示),内存条(用于存储).把每个零件封装出抽象父类,并且提供不同的厂商生产不同的零件,例如Intel厂商和Lenovo厂商.创建 ...

  6. 【b站黑马程序员C++视频学习笔记-多态案例二-制作饮品】

    多态案例二-制作饮品 利用多态实现制作咖啡和茶水 Coffee和Tea继承了抽象类AbstractDrinking,并重写了AbstractDrinking的抽象函数 #include<iost ...

  7. 学习笔记 | 多态案例2-制作饮品

    多态案例二-制作饮品 案例描述:制作饮品的大致流程为:煮水 - 冲泡 - 倒入杯中 - 加入辅料 利用多态技术实现本案例,提供抽象制作饮品基类,提供子类制作咖啡和茶叶. #include <io ...

  8. #学习笔记#(14)select隐藏右侧三角鼠标移入展开-jQuery

    原理: 利用div的overflow:hidden,使select右侧图标隐藏消失.//然而opera浏览器的边框无法去除= =,不知何解. jQuery: mouseenter,鼠标移入select ...

  9. Java学习笔记——多态(实例详解)

    多态是某一事物,在不同时刻体现出来的不同的状态 就比如猫,狗,狼都是动物,我们可以说猫是动物,说狗是动物 但我们不能说动物是猫,动物是狼.也不能说猫是狗,或者狗是狼. 上面这几点都会在多态中体现出来 ...

最新文章

  1. codility上的问题 (22)
  2. 再印!抽奖!有三AI学习扑克牌新一批货到
  3. Elasticsearch之CURL命令的version控制
  4. c#中将HTML文件转换成PDF文件
  5. 别给小偷可乘之机!日本山形县警方呼吁民众“锁门”
  6. [ZJOI2010] 贪吃的老鼠(二分+差分+神仙建图网络流)
  7. OllyDbg笔记-初识PE文件(nag窗口破解)
  8. Python高级——魔法属性和方法
  9. linux内存管理(十二)-直接页面回收
  10. python中属性与方法_python中属性和方法的动态绑定
  11. 夺命雷公狗---微信开发18----删除自定义菜单
  12. Neotec WELLFLO V8.1.6 油气井生产 模拟软件
  13. 六级(2020/12-2) Section B
  14. 听风辨器,神功护体——IT运维人员的九阳神功(中)
  15. unix 创建html文件路径,Btrfs 创建目录和文件的操作
  16. Oracle GL - 使用标准程序获取/创建CCID
  17. 电脑桌面文件不见了怎么恢复?
  18. 大数据开发认知--spark
  19. 标准差和均方根误差的区别
  20. 【转载】SCI投稿过程总结、投稿状态解析、拒稿后对策及接受后期相关问答

热门文章

  1. 【kafka】confluent_kafka重置offset
  2. alpha事后诸葛亮
  3. linux下利用openssl来实现证书的颁发(详细步骤)--转载和修改
  4. Intent打开Activity
  5. Client Dimensions , offsetHeight , scrollTop 属性详解
  6. GridView 里的删除不起作用
  7. winform_界面美化设计_显示/隐藏侧边栏
  8. python 苹果李子橙_Python模块知识6:OS、SYS模块
  9. dbeaver连接mysql 驱动jar_Jmeter(七) 从入门到精通 建立数据库测试计划实战lt;MySQL数据库gt;(详解教程)...
  10. mysql架构设计书籍推荐_最近很火的MySQL:抛开复杂的架构设计,MySQL优化思想基本都在这...