"受保护"和"虚拟/覆盖"之间的区别

Ore*_*aki 9 c# oop

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

编辑:

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

Ada*_*dam 15

它们肯定不是一样的.

所述protected改性剂设置能见度 的字段或方法的:这样的构件只能从它在或从派生类中定义的类访问.

所述virtual修饰符指定,该方法将它应用到overridden在派生类.

可以组合这些修饰符:可以保护方法和虚拟方法.


Joh*_*son 8

  • protected表示当前类和派生类的private
  • 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");
    }
}
Run Code Online (Sandbox Code Playgroud)


Cha*_*ana 7

我可以说最重要的区别virtual在于,这会导致编译器在以多态方式调用方法成员时,将编译后的代码绑定到哪个实现。当您从客户端代码调用类的成员时,其中对象的实际类型是派生类foo,但它被调用的变量实际上被类型化(声明)为某个基类,例如bar,声明为的成员virtual将绑定到实际对象类型中的实现,(或到具有实现的对象类型的最派生基类)。声明为 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"
Run Code Online (Sandbox Code Playgroud)

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"
Run Code Online (Sandbox Code Playgroud)