override new shadowing

前端之家收集整理的这篇文章主要介绍了override new shadowing前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

1.什么时候使用override?什么时候使用new? 什么叫shadowing?
(重写父类方法的时候用override以实现多态,如果父类中的方法不是virtual的也不是abstract的才使用new,shadowing不懂)

Overloads,Overrides,Overridable,Shadows

先是基本概念:

overloads(重载):与现有成员相同的名称来声明属性方法,但参数列表与原始成员不同;

overrides(重写):将重写从基类继承的成员;

Overridable(可覆盖的):指定属性或过程可由派生类中同名的属性或过程进行重写;

shadows:隐藏基类中一个同名元素或一组重载元素。

Overloads

之前是一直很confuse,在VS里写代码的时候貌似都没用过overloads,后来查了资料才知道Overloads是VB.NET beta 版遗留下来的关键字,现在已经可以不用写了,仍然存在是为了兼容已有的beta版代码。 其基本用法如下:


Public Overloads Sub a()
Debug.Writeline("a()")
End Sub
Public Overloads Sub a(ByVal para1 As Integer)
Debug.Writeline("a(ByVal para1 As Integer)")
End Sub
Public Sub Demo()
a()
a(1)
End Sub

(此例说明Overloads的作用,就是允许同名函数的存在,前提是有不同的参数。)

在VS里,overloads很多时候都可以省略不写,不过在一些涉及继承方面的内容时,还是需要用到overloads的。在子类中我们希望添加一个重载方法,增强子类功能时候,亦即重载基类中地方法时,就需要用到Overloads. 如下例子:


'基类
Public Class Person
private mName as string
private mBirthday as Date

Public Property Name() as String
Get
Return mName
End Get
Set(Byval value as string)
mName = value
End Set
End Property

Public Property Birthday() as String
Get
Return mBirthday
End Get
Set(Byval value as string)
mBirthday = value
End Set
End Property

End Class

'子类
Public Class Employee
Inherts Person

Private mHireDate as Date
Private mSalary as Double
Private mNames as New Generic.Dictionary(of NameTypes,String)
Public Property Name(byval 1 as NameTypes) as String
Get
Return mNames(type)
End Get
Set(Byval value as string)
if mNames.ContainsKey(type) then
mNames.Item(type)=value
Else
mNames.Add(type,value)
end if
End Set
End Property
End Class
'(如果这里省略了Overload关键字,Name方法的信实现代码就会遮蔽原来的实现代码

Overridable,Overrides and shadow

在.NET中实现多态有两种方式,覆盖(overrides)和投影(shadow),而投影又分为Shados by Name(就是我们一般用的shadows)和Shadows by

signature(参数序列).

Public Class TheBase
Public Overridable Sub a()
Debug.Writeline("TheBase")
End Sub
End Class
Public Class TheInherited
Inherits TheBase
Public Overrides Sub a()
Debug.Writeline("TheInherited")
End Sub
End Class
Public Class TheShadowed
Inherits TheInherited
Public Shadows Sub a()
Debug.Writeline("TheShadowed")
End Sub
End Class

'情况一:
Dim c As TheBase
c = New TheBase()
c.a() ' 输出 TheBase
c = New TheInherited()
c.a() ' 输出 TheInherited
c = New TheShadowed()
c.a() ' 输出 TheInherited
'情况二:
Dim c As TheInherited
c = New TheBase()
c.a() ' 错误!无效的转换。
c = New TheInherited()
c.a() ' 输出 TheInherited
c = New TheShadowed()
c.a() ' 输出 TheInherited
'情况三:
Dim c As TheShadowed
c = New TheBase()
c.a() ' 错误!无效的转换。
c = New TheInherited()
c.a() ' 错误!无效的转换。
c = New TheShadowed()
c.a() ' 输出 TheShadowed

此例说明Overridable、Overrides、Shadows的用法

请注意TheBase里面的Overridable,如果没有这一句,后面类TheInherited将无法声明同名过程a(),而TheShadows仍然可以。

Overridable 的意思是:可以被重写的。默认情况下,似乎不能重写基类中方法的行为的,基类必须显式地使用Overridable关键字,指出允许重写地方法

Overrides 的意思是:重写原来的,一般用于子类重写父类方法。如果没有Overrides关键字,当实现一个与基类中某一方法同名同参数地方法时,会得到一个编译错误

Shadows 的意思是: 指示该变量隐藏基类中的同名编程元素或重载元素集。任何类型的声明元素均可用其他任何类型来隐藏。隐藏的元素在隐藏它的派生类中不可用。仅可以在模块、命名空间或文件级中使用 Shadows。这意味着可以在源文件中或者在模块、类或结构内(但不在过程内)声明隐藏变量。如果指定了 Shadows,也可以省略Dim关键字。不能在同一变量声明中同时指定 Static 和 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()了。

override overload hide obscure shadow概念区别

1。一个实例方法可以覆写(override)在其超类中可访问到的具有相同签名的所有实例方法,VM 将基于实例的
运行期类型来选择要调用的覆写方法

2。一个域、静态方法或成员类型可以分别隐藏(hide)在其超类中可访问到的具有相同名字(对方法而言就是相同的方法签名)的所有域、静态方法或成员类型。隐藏一个成员将阻止其被继承

3。在某个类中的方法可以重载(overload)另一个方法,只要它们具有相同的名字和不同的签名。由调用所指定的重载方法是在编译期选定的

4。遮掩(obscure) 一个变量可以遮掩具有相同名字的一个类型(比如System的一个String类型和System.out中的System),只要它们都在同一个范围内:如果这个名字被用于变量与类型都被许可的范围,那么它将引用到变量上。相似地,一个变量或一个类型可以遮掩一个包。
例子:
public class Obscure {
static String System; // Obscures type java.lang.System
public static void main(String[ ] args) {
// Next line won't compile: System refers to static field
System.out.println(“hello,obscure world!”);
}
}

5。一个变量、方法或类型可以分别遮蔽(shadow)在一个闭合的文本范围内的具有相同名字的所有变量、方法或类型。如果一个实体被遮蔽了,那么你用它的简单名是无法引用到它的;根据实体的不同,有时你根本就无法引用到它

////////////////////////////////////////////////////////////现在举一个shadow的例子,注意哦,很重要

package com.yinbodotcc;
public class PrivateClass
{
public void sleep(String a)
{
System.out.println(".."+a);
}

public static void sleep2(String a)
{
System.out.println(".."+a);
}

public void call()
{
new Thread(){
public void run()
{
//从Thread 那里继承到匿名类中的sleep 方法遮蔽(shadow)
//了我们想要调用的sleep方法,所以直接sleep("hello")找不到匹配的,所以
//不可以,会编译出错的。
//这个时候需要用 PrivateClass.this 来修饰一下子
//想法,如果取一个不同的名字,则就没有这个问题了。
PrivateClass.this.sleep("3");
sleep2("4");
}
}.start();

new Thread(new Runnable(){
public void run(){
//下面可以的原因是由于,Runnable接口里面没有定义sleep函数
sleep("4");
}
}).start();
}

public static void main(String[] args)
{
PrivateClass p=new PrivateClass();
p.call();
}
}

2.解释virtual、sealed、override和abstract的区别
(virtual申明虚方法的关键字,说明该方法可以被重写,sealed说明该类不可被继承,override重写基类的方法,abstract申明抽象类和抽象方法的关键字,抽象方法不提供实现,由子类实现,抽象类不可实例化。)

new

new 关键字可以显式隐藏从基类继承的成员。隐藏继承的成员意味着该成员的派生版本将替换

基类版本。也就说在使用派生类的方法调用方法是New关键字新定义出来的方法,而不是基类的

方法

在不使用 new 修饰符的情况下隐藏成员是允许的,但会生成警告。使用 new 显式隐藏成员会取

消此警告,并记录代之以派生版本这一事实。

Virtual

Virtual 关键字允许在派生类中重写这些对象,默认情况下,方法是非虚拟的,不可以重写非


方法,virtual关键字不可以与static、abstract、private、override一起使用。

Virtual关键字又是和override紧密不可分的,如果要实现Virtual方法就必须要使用override

或new关键字(new和override产生的机理不同)。

abstract

在类声明中使用abstract修饰符以指示某个类只能是其他类的基类。标记为抽象或包含在

抽象类中的成员必须通过从抽象类派生的类来实现。抽象类不能实例化。

抽象方法声明不提供实际的实现,所以没有方法体;方法声明只是以一个分号结束,并且

在签名后没有大括号 ({ })。

sealed

密封方法会重写基类中的方法,但其本身不能在任何派生类中进一步重写。密封类不能被

继承。

当应用于方法属性时,sealed修饰符必须始终与override一起使用。

Override

Override关键字主要是提供派生类对基类方法的新实现,重写的基类方法必须和Override的方

法具有相同的签名

3.Foo.Bar,Version=2.0.205.0,Culture=neutral,PublicKeyToken=593777ae2d274679d 解释这个字符串每个部分的重要性和作用
(程序集的名字、版本、Culture不知道,公钥,这些用于GAC中申明一个唯一的程序集)

一个程序集通常包括4个自定义属性,用来惟一识别程序集,它们是文件名(无扩展名)、版本号、区域性标识和公钥标记,比如:

  "Hello,version=1.0.0.0,culture=neutral,publicKeyToken=9ebd24cc40ff21fd"

  其中publicKeyToken是公钥的64位散列值,可以唯一标识程序集,拥有公钥标记的程序集称为强名称程序集,强名称程序集可以防篡改;可以安装到GAC中,为多个程序集所共享;还可以实施版本策略(不同版本的强名称程序集被认为是不同的程序集)。而公钥标记为空的程序集只能存在于所引用的程序集的目录以及子目录中,也无法实施版本策略(引用它的程序集会忽略版本号)。

4.解释public、protected、private和internal的区别

public可被内外访问

protected只能被内部和之类访问

private只能内部访问

internal只能在该程序集中被访问

5.使用Primary Interop Assembly (PIA)有什么好处?
反射,为测试方法加了Attribute

6.NUnit是通过什么机制获知需要测试哪些方法的?
(将发生的异常对象抛出,另一个只是抛出异常,并没有抛出原异常对象)

7.catch(Exception e){throw e;}和catch(Exception e){throw;}的区别

8.typeof(foo)和myFoo.GetType()的区别?

9.public class c{ public c(string a) : this() {;}; public c() {;} } 解释第一个构造函数中发生了什么?这个构造函数有什么用?
(第一个构造函数调用了第二个构造函数,这个构造函数构造了一个c对象的实例。)

10.this是干嘛用的?能够用在static方法


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/liangweiwei130/archive/2009/07/19/4360863.aspx

原文链接:https://www.f2er.com/vb/261988.html

猜你在找的VB相关文章