sealed,new,virtual,abstract与override

1.sealed---“断子绝孙”

密封类不能被继承,不会有子类。密封方法可以重写基类中的方法。

2.new---“你是你的,我是我的”

new关键字用于显式隐藏从基类继承的成员,也就是说在使用派生类时调用的方法是new关键字新定义出来的方法,而不是基类的方法。在不使用new修饰符的情况下隐藏成员是允许的,但会生成警告。使用new显式隐藏成员会取消此警告,并使用派生类新定义的方法。即:好比是不用祖宗的东西,而是用自己创造的东西。

using System.Text;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Child c = new Child();
            c.SayHello();   //显示我是子类
            ((Parent)c).SayHello(); //显示我是父类
        }
    }

    class Parent
    {
        public void SayHello()
        {
            Console.Write("我是父类");
        }
    }
    class Child:Parent
    {
        public new void SayHello()
        {
            Console.Write("我是子类");
        }
    }
}

3.virtual---"为了子孙后代"

用于修改方法或属性的声明,修改后的方法或属性称作虚成员。默认情况下方法是非虚拟的。不能将virtual修饰符和static,abstract,override一起使用。调用虚方法时将为重写成员检查该对象的运行时的类型,如果没有派生类重写该成员,则它可能是原始成员。

  • 在静态属性上使用virtual是错误的
  • 通过使用override修饰符的属性声明,在派生类中重写虚拟继承属性。

4.abstract---“我是上帝”

abstract修饰符可以和类,方法,属性,索引器及事件一起使用。

在类声明中使用abstract修饰符,以指示该类只能是其他类的基类。标记为抽象或包含在抽象类中的成员必须通过从抽象派生的类来实现。

抽象类具有以下特性:

  • 抽象类不能实例化
  • 抽象类可以包含抽象方法和抽象访问器
  • 不能用sealed修饰符修改抽象类,这意味着该类不能被继承。
  • 从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实现。
  • 在方法或属性中使用abstract指示此方法或属性不包含实现
抽象方法具有以下特性:
  • 抽象方法是隐式的virtual方法。
  • 抽象方法不提供实际的实现,所以没有方法体。并且在声明后没有大括号”}“
  • 实现由override提供,他是非抽象类成员
  • 在静态属性使用abstract修饰符是错误的
abstract是一种抽象,好比上帝,是人们对神的抽象,看似什么都能干,其实什么都干不了、

5.override---一手遮天

使用override修饰符来修改方法,属性,索引器,或事件。主要是提供派生类对基类方法的新实现。覆盖上面的abstract,virtual两种关键字修饰的成员。

不能重写非虚拟方法或者静态方法。

new和override的区别:

  • 用override的基类的方法必须要用virtual,而new不必要。
  • 用一个基类的对象调用基类的virtual方法时,override重写的派生类的方法全被访问,而new重写的派生类中的方法不会被访问。

using System;

namespace ConsoleApplication1
{
    public class BaseClass
    {
        public BaseClass()
        {
            Console.WriteLine("基类构造");
        }
        //使用virtual才可以在子类中使用override,而new不要
        public virtual void Method()
        {
            Console.WriteLine("基类.Method()");
        }
    }
    public class DeriveClassA : BaseClass
    {
        public DeriveClassA()
        {
            Console.WriteLine("类A.构造");
        }
        public override void Method()
        {
            //base.Method();
            Console.WriteLine("类A.Method() in override");
        }
    }

    public class DeriveClassB : BaseClass
    {
        public DeriveClassB()
        {
            Console.WriteLine("类B.构造");

        }
        public new void Method()
        {
            //base.Method();
            Console.WriteLine("类B.Method() in new");
        }
    }
    class Program
    {
        static void Main(string[] args)
        {
            BaseClass ba1 = (BaseClass)new DeriveClassA();//类型转换
            //用override重写方法,是基类的一个派生,所以这里通过基类的虚函数,会访问到派生类的方法
            ba1.Method();
            Console.WriteLine("==========");
            BaseClass ba2 = (BaseClass)new DeriveClassB();
            //用new重写方法,是基类的一个派生,所以这里基类调用的时候,访问基类的方法
            ba2.Method();
            Console.WriteLine("==========");

            DeriveClassA a1 = new DeriveClassA();
            a1.Method();
            Console.WriteLine("==========");

            DeriveClassB b2 = new DeriveClassB();
            b2.Method();
            Console.WriteLine("==========");
            Console.Read();
        }
    }
}

运行结果:


原文地址:https://www.cnblogs.com/fornet/p/2976153.html