当我有“虚拟/覆盖”时,我无法理解“受保护”的需要或目的,如果它们几乎相同,有人可以解释我需要什么这两件事。
编辑:
感谢所有帮助者,我现在明白“受保护”仅用于可见性目的,而虚拟/覆盖用于类行为。
它们当然不几乎相同。
protected
修饰符设置字段或方法的可见性 :此类成员只能从定义它的类或派生类访问。
virtual
修饰符指定它所应用的方法可以在overridden
派生类中。
这些修饰符可以组合使用:方法可以是受保护的和虚拟的。
也许使用一些代码而不是你可能已经阅读过的东西会更好,这里有一个你可以玩的小示例。尝试删除注释(//),您可以看到编译器告诉您无法访问属性
[TestFixture]
public class NewTest
{
[Test]
public void WhatGetsPrinted()
{
A a= new B();
a.Print(); //This uses B's Print method since it overrides A's
// a.ProtectedProperty is not accesible here
}
}
public class A
{
protected string ProtectedProperty { get; set; }
private string PrivateProperty { get; set; }
public virtual void Print()
{
Console.WriteLine("A");
}
}
public class B : A
{
public override void Print() // Since Print is marked virtual in the base class we can override it here
{
//base.PrivateProperty can not be accessed hhere since it is private
base.ProtectedProperty = "ProtectedProperty can be accessed here since it is protected and B:A";
Console.WriteLine("B");
}
}
我可以说,最重要的区别virtual
在于,这会导致编译器在多态调用方法成员时,将编译后的代码绑定到哪个实现。当您从客户端代码调用类的成员时,其中对象的实际类型是派生类foo
,但它被调用的变量实际上是作为某个基类类型(声明)的,比如bar
声明为的成员virtual
将绑定到实际对象类型中的实现,(或到具有实现的对象类型的最派生基类)。未声明为虚拟的成员将绑定到声明该变量的类型的实现。
A. 虚拟。那么,如果该成员被声明为虚拟,即使该变量被声明为基类型,派生类中的实现也会被执行。
public class Animal
{ public virtual Move() { debug.Print("Animal.Move()"); }
public class Bird: Animal
{ public virtual override Move() { debug.Print("Bird.Move()"); }
Animal x = new Bird();
x.Move(); // Will print "Bird.Move"
B.不是虚拟的。当成员未声明为virtual
时,将根据执行该方法的变量的声明类型来选择实现。因此,如果您有一个 Bird 对象,在变量 x 中声明为“Animal”,并且您调用了在两个类中都实现的方法,编译器将绑定到 Animal 类中的实现,而不是 Bird,即使该对象是真的是一只鸟。
public class Animal
{ public Move() { debug.Print("Animal.Move()"); }
public class Bird: Animal
{ public Move() { debug.Print("Bird.Move()"); }
Animal x = new Bird();
x.Move(); // Will print "Animal.Move"
我认为您需要正确理解以上两件事,因为两者都有不同的目的。
protected是类型或成员只能由同一类或结构中的代码或派生类中的代码访问。
virtual关键字用于修改方法、属性并允许它在派生类中被覆盖。