VB.NET--OVERLOADS,OVERRIDES,SHADOWS

  
    
1 Public Class TheBase
2 Public Overridable Sub a()
3 Debug.Writeline( " TheBase " )
4 End Sub
5 End Class
6
7 Public Class TheInherited
8 Inherits TheBase
9 Public Overrides Sub a()
10 Debug.Writeline( " TheInherited " )
11 End Sub
12 End Class
13
14 Public Class TheShadowed
15 Inherits TheInherited
16 Public Shadows Sub a()
17 Debug.Writeline( " TheShadowed " )
18 End Sub
19 End Class
20
21 ' 情况一:
22   Dim c As TheBase
23 c = New TheBase()
24 c.a() ' 输出 TheBase
25   c = New TheInherited()
26 c.a() ' 输出 TheInherited
27   c = New TheShadowed()
28 c.a() ' 输出 TheInherited
29
30 ' 情况二:
31 Dim c As TheInherited
32 c = New TheBase()
33 c.a() ' 错误!无效的转换。
34 c = New TheInherited()
35 c.a() ' 输出 TheInherited
36 c = New TheShadowed()
37 c.a() ' 输出 TheInherited
38
39 ' 情况三:
40 Dim c As TheShadowed
41 c = New TheBase()
42 c.a() ' 错误!无效的转换。
43 c = New TheInherited()
44 c.a() ' 错误!无效的转换。
45 c = New TheShadowed()
46 c.a() ' 输出 TheShadowed

此例说明Overridable、Overrides、Shadows的用法。  
  请注意TheBase里面的Overridable,如果没有这一句,后面类TheInherited将无法声明同名过程a(),而TheShadows仍然可以。  
  Overridable   的意思是:可以被重写的。  
  Overrides   的意思是:重写原来的。  
  Shadows   的意思是:这个函数/过程/变量跟我的父类没有任何关系,它是一个全新的过程。  
   
  在运行的例子中我们可以清晰地看到,无论变量c的定义是什么,VB.NET都会尽量寻找到最后被定义的那个成员。也就是说,如果被重写了,那么就找“从变量类型开始,到这个变量所指对象实际上的类为止,最后一次被重写(Overrides)的那个成员”。(当然,如果找不到,那么还会往变量类型的祖先那个方向上去找。)  
   
  简单点讲就是说,无论c怎么定以,如果他指向的是一个TheBase,他就找“到TheBase为止最后一次被重写的那个Sub   a()”。如果他指向的是一个TheInherited,就找“到TheInherited为止最后一次被重写的那个Sub   a()”,也就是TheInherited里面的那个。  
   
  对于TheShadowed来说,情况稍微复杂一点:  
  由于TheShadowed里面所写的那个a()被声明为Shadows的,也就是说这个a()跟TheBase和TheInherited里面的没有关系,于是从变量c的基类(TheBase)开始找,一直找到变量所指对象的类型TheShadowed,发现变量c的类型(无论是TheBase还是TheInherited)里面的那个a()最后一次被重写是在TheInherited里面(注意:TheShadows里面的a()跟它没关系),于是只要c不是Dim   ..   As   TheShadows,那么就会选择调用TheInherited里面的a()了。

重载规则

用同样名称添加两个或更多属性或方法可以创建类的一个重载成员。除了重载派生成员,每一个重载成员必须具有不同的参数列表。当重载属性或过程时,下面的项不能用作区分特征:

  • 应用于成员或成员参数的修饰符,如 ByVal 或 ByRef。

  • 参数名

  • 过程的返回类型

  重载时关键字 Overloads 是可选的,但如果任一重载成员使用了该 Overloads 关键字,则其他所有同名重载成员也必须指定该关键字。

  派生类可以用具有相同参数和参数类型的成员重载继承成员,该过程称为“按名称和签名隐藏”。如果按名称和签名隐藏时使用了 Overloads 关键字,将使用成员的派生类实现而不是基类中的实现,并且该成员的所有其他重载对于派生类的实例都可用。

  如果用一个具有相同参数和参数类型的成员重载继承成员时省略 Overloads 关键字,则该重载称为“按名称隐藏”。按名称隐藏替换成员的继承实现,使所有其他重载对于派生类及由其派生的类的实例都不可用。

  Overloads 和 Shadows 修饰符不能同时被同一个属性或方法所使用。

你可能感兴趣的:(override)