Modifiers: virtual, override, new, abstract, sealed, internal

  • internal

    • 声明类、类成员、接口或接口成员具有内部可见性。
    • internal 修饰符使类、接口或成员仅在当前包中可见。 当前包之外的代码不能访问 internal 成员。只有在同一程序集的文件中,内部类型或成员才是可访问的
    • 在全局范围内,internal 修饰符与 public 修饰符相同。
    • 不能将 internal 修饰符与其他任何可见性修饰符(public、private 或 protected)组合。 可见性修饰符相对于它们的定义范围。
  • sealed
    • 当对一个类应用 sealed 修饰符时,此修饰符会阻止其他类从该类继承。
    • 在重写基类中的虚方法或虚属性的方法或属性上使用 sealed 修饰符。 这将使您能够允许类从您的类继承,并防止它们重写特定的虚方法或虚属性。
    • 当应用于方法或属性时,sealed 修饰符必须始终与 override 一起使用。
  • abstract
    • abstract 修饰符指示所修饰的内容缺少实现或未完全实现。 abstract 修饰符可用于类、方法、属性、索引器和事件。 在类声明中使用 abstract 修饰符以指示某个类只能是其他类的基类。 标记为抽象或包含在抽象类中的成员必须通过从抽象类派生的类来实现。
    • 抽象类不能实例化。
    • 抽象类可以包含抽象方法和抽象访问器。
    • 不能用 sealed(C# 参考) 修饰符修饰抽象类,因为这两个修饰符的含义是相反的。 采用 sealed 修饰符的类无法继承,而 abstract 修饰符要求对类进行继承。
    • 从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实际实现。
    • 抽象方法是隐式的虚方法(virtual)。
    • 只允许在抽象类中使用抽象方法声明。
    • 在抽象方法声明中使用 static 或 virtual 修饰符是错误的。
    • 实现接口的抽象类可以将接口方法映射到抽象方法上。
  • new
    • 在用作声明修饰符时,new 关键字可以显式隐藏从基类继承的成员。 隐藏继承的成员时,该成员的派生版本将替换基类版本。 虽然可以不使用 new 修饰符来隐藏成员,但将收到编译器警告。 如果使用 new 来显式隐藏成员,将禁止此警告。
    • 对同一成员同时使用 new 和 override 是错误的做法,因为这两个修饰符的含义互斥。 new 修饰符会用同样的名称创建一个新成员并使原始成员变为隐藏。 override 修饰符会扩展继承成员的实现。
  • override
    • 要扩展或修改继承的方法、属性、索引器或事件的抽象实现或虚实现,必须使用 override 修饰符。
    • override 方法提供从基类继承的成员的新实现。重写的基方法必须与 override 方法具有相同的签名。
    • 不能重写非虚方法或静态方法。 重写的基方法必须是 virtual、abstract 或 override 的。
    • override 声明不能更改 virtual 方法的可访问性。 override 方法和 virtual 方法必须具有相同的访问级别修饰符
    • 您不能使用 new、static 或 virtual 修饰符来修改 override 方法。
    • 在 Derived 的一个实例中调用 method 时,C# 编译器将首先尝试使该调用与最初在 Derived 上声明的 method 版本兼容。 重写方法不被视为是在类上进行声明的,而是在基类上声明的方法的新实现。 仅当
      C# 编译器无法将方法调用与 Derived 上的原始方法匹配时,它才尝试将该调用与具有相同名称和兼容参数的重写方法匹配。
  • virtual
    • virtual 关键字用于修饰方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。
    • 默认情况下,方法是非虚拟的。 不能重写非虚方法。
    • virtual 修饰符不能与 static、abstract, private 或 override 修饰符一起使用。

Examples:

public abstract class A
   {
      public abstract void Do();
      public virtual void DrawLine() { Console.WriteLine("A:DrawLine"); }
      public virtual void DrawPoint() { Console.WriteLine("A:DrawPoint"); }
      public virtual void DoWork() { Console.WriteLine("A:DoWork"); }
   }

   public class B : A
   {
      public override void Do() { Console.WriteLine("B:DO"); }
      public new void DrawLine() { Console.WriteLine("B:DrawLine"); }
      public override void DrawPoint() { Console.WriteLine("B:DrawPoint"); }
      public override void DoWork() { Console.WriteLine("B:DoWork"); }
   }

   public class C : B
   {
      public sealed override void DoWork() { Console.WriteLine("C:DoWork"); }
   }

   public class D : C
   {
      // Attempting to override DoWork causes compiler error CS0239.
      //public override void DoWork() {}
      public new void DoWork() { Console.WriteLine("D:DoWork"); }
   }

   // Only accessible within the same assembly
   internal class MyInternalClass
   {
      public string Value { get; set; }
   }

   //public sealed class MySealedClass { }
   //public class Derived : MySealedClass { } // error CS0509: '': cannot derive from sealed type

   interface I
   {
      void M();
   }
   abstract class AC : I
   {
      public abstract void M();
   }

   public class Base
   {
      public virtual void DoWork(int param) { Console.WriteLine("Base:DoWork(int)"); }
   }

   public class Derived : Base
   {
      public override void DoWork(int param) { Console.WriteLine("Derived:DoWork(int)"); }
      public void DoWork(double param) { Console.WriteLine("Derived:DoWork(double)"); }
   }

   A a = new B();
   a.DrawLine(); // output A:DrawLine
   a.DrawPoint(); // output B:DrawPoint
   a.Do(); // output B:DO

   D d = new D();
   d.DoWork(); // output D:DoWork
   C c = (C)d;
   c.DoWork(); // output C:DoWork
   B b = (B)d;
   b.DoWork(); // output C:DoWork

   int val = 5;
   Derived der = new Derived();
   der.DoWork(val);  // Calls DoWork(double).
   ((Base)der).DoWork(val);  // Calls DoWork(int) on Derived.

Modifiers: virtual, override, new, abstract, sealed, internal

时间: 2024-11-05 12:16:43

Modifiers: virtual, override, new, abstract, sealed, internal的相关文章

c#中的 virtual override 和abstract 以及sealed

1.如果父类方法没有加virtual关键字,即不是一个虚方法,则在子类中只能隐藏基类方法,而不能覆盖. 2.如果父类方法加了virtual关键字,即它是一个虚方法,在子类中一样可以隐藏. 3.如果子类实现了父类相同的方法(相同的方法名称及签名),而没有new,在编译时会报警,但编译仍然能够通过! 4.调用父类方法:base.方法名() 5.abstract类是一个抽象类,不能被实例化 new 和override的区别 1.override重写虚方法,那么就只剩下重写以后的方法; 2.new隐藏基

C#基础知识(base、this、new、override、abstract、virtual、static)

前言 本文主要来讲解一下C#中,自己觉得掌握的不怎么样或者用的不多,不太熟悉的关键字,主要包括base.this.new.override.abstract.virtual以及针对static字段和static构造函数之间的执行问题. base关键字 base 关键字用于在派生类中实现对基类公有或者受保护成员的访问,但是只局限在构造函数.实例方法和实例属性访问器中: 调用基类上已被其他方法重写的方法. public class Father { public virtual void Say()

abstract,virtual,override个人

1.abstract 可以修饰类和方法,修饰方法时只声明不实现: 2.继承实现abstract类必须通过override实现abstract声明的方法,而virtual方法可选择override(重写)实现: 3.

abstract,virtual,override

1.abstract 可以修饰类和方法,修饰方法时只声明不实现: 2.继承实现abstract类必须通过override实现abstract声明的方法,而virtual方法可选择override(重写)实现: 3.

virtual方法和abstract方法

在C#的学习中,容易混淆virtual方法和abstract方法的使用,现在来讨论一下二者的区别.二者都牵涉到在派生类中与override的配合使用. 一.Virtual方法(虚方法) virtual 关键字用于在基类中修饰方法.virtual的使用会有两种情况: 情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法.那么在对派生类实例的调用中,该虚方法使用的是基类定义的方法. 情况2:在基类中定义了virtual方法,然后在派生类中使用override重写该方法.那么在对派生

virtual方法和abstract方法的使用(轉載)

在C#的学习中,容易混淆virtual方法和abstract方法的使用,现在来讨论一下二者的区别.二者都牵涉到在派生类中与override的配合使用. 一.Virtual方法(虚方法) virtual 关键字用于在基类中修饰方法.virtual的使用会有两种情况: 情况1:在基类中定义了virtual方法,但在派生类中没有重写该虚方法.那么在对派生类实例的调用中,该虚方法使用的是基类定义的方法. 情况2:在基类中定义了virtual方法,然后在派生类中使用override重写该方法.那么在对派生

如何使用virtual/override在属性事件以及索引上

using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace nange_1 { class A { private int myint = 5; virtual public int Myint { get { return myint; } } } class B : A { private int myint = 10; override public int

虚方法virtual、抽象方法abstract、接口interface区别

接口.抽象类.抽象方法.虚方法: 这四个名词时非常容易混淆的: 首先说一下接口 与抽象类 的异同: 相同点: 1.他们都不能实例化自己,也就是说都是用来被继承的. 2.抽象类中的抽象方法和接口方法一样,都不能有方法体 不同点: 1.抽象类里可以有字段,接口中不能有字段. 2.抽象类中的普通方法可以有方法体,而接口方法没有方法体. 3.接口中的方法不能有访问修饰符,抽象类中的抽象方法被继承,需要override重写 . 4.接口更像是一种规范,一种约束. 5.一个子类只能继承一个抽象类,但却可以继

虚方法(virtual)和抽象方法(abstract)的区别

虚方法和抽象方法都可以供派生类重写. 虚方法必须有实现部分,抽象方法必须没有实现部分,抽象方法是一种强制派生类覆盖的方法,否则派生类将不能被实例化.如: class Program { static void Main(string[] args) { C c = new C(); D d = new D(); } } abstract class A { public virtual void Sleep() { } public virtual void N(); //报错,虚方法必须有实现