11

当我有“虚拟/覆盖”时,我无法理解“受保护”的需要或目的,如果它们几乎相同,有人可以解释我需要什么这两件事。

编辑:

感谢所有帮助者,我现在明白“受保护”仅用于可见性目的,而虚拟/覆盖用于类行为。

4

4 回答 4

20

它们当然几乎相同。

protected修饰符设置字段或方法的可见 :此类成员只能从定义它的类或派生类访问。

virtual修饰符指定它所应用的方法可以overridden派生类中。

这些修饰符可以组合使用:方法可以是受保护的和虚拟的。

于 2012-10-30T18:43:57.593 回答
8
  • protected表示当前类和派生类的私有
  • virtual意味着它可以按原样使用,但也可以在派生类中被覆盖

也许使用一些代码而不是你可能已经阅读过的东西会更好,这里有一个你可以玩的小示例。尝试删除注释(//),您可以看到编译器告诉您无法访问属性

[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");
    }
}
于 2012-10-30T18:42:50.770 回答
7

我可以说,最重要的区别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"
于 2012-10-30T19:07:57.553 回答
3

我认为您需要正确理解以上两件事,因为两者都有不同的目的。

protected是类型或成员只能由同一类或结构中的代码或派生类中的代码访问。

virtual关键字用于修改方法、属性并允许它在派生类中被覆盖。

于 2012-10-30T18:45:39.617 回答