继承相关关键字Virtual、Abstract、override、Interface、final、Sealed全解析

因为需要经常切换C++/C#平台编程,一次性解析下这些关键字吧,写多了容易混。。。
首先呢这些关键字不是两个平台都有的,具体如下:

VirtualAbstractoverridefinalInterfaceSealed
C#×
C++×××

Virtual与override、final、Sealed
C#:
1.virtual 关键字用于修饰方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。 例如,此方法可被任何继承它的类重写。
2.override方法,是在子类中重写父类中的方法,两个函数的函数特征(函数名、参数类型与个数)相同。用于扩展或修改继承的方法、属性、索引器或事件的抽象或虚拟实现。
3.没有final关键字。
4.Sealed关键字应用于某个类时,sealed 修饰符可阻止其他类继承自该类①。 还可以对替代基类中的虚方法或属性的方法或属性使用 sealed 修饰符。 这使你可以允许类派生自你的类并防止它们替代特定虚方法或属性②。功能类似于C++中的final关键字。
virtual+override举例:

public class car
{
   public virtual void Weight()
   {
       Console.WriteLine("输出车重");
   }
}
public class truck : car
{
    public override void Weight()
    {
        Console.WriteLine("卡车车重10吨");
    }
}

Sealed①举例

class A {}
sealed class B : A {}
class C : B {}//报错

Sealed②举例

    class X
    {
        protected virtual void F() { Console.WriteLine("X.F"); }
        protected virtual void F2() { Console.WriteLine("X.F2"); }
    }
    
    class Y : X
    {
        sealed protected override void F() { Console.WriteLine("Y.F"); }
        protected override void F2() { Console.WriteLine("Y.F2"); }
    }
    class Z : Y
{
    // 此处试图重写 F 时报错 error CS0239.
    protected override void F() { Console.WriteLine("Z.F"); }
    protected override void F2() { Console.WriteLine("Z.F2"); }
}

C++:
1.virtual是定义C++中虚函数的关键字,在使用virtual之前,C++对成员函数使用静态联编,而使用virtual,并且在调用函数时是通过指针或引用调用,C++则对成员函数进行动态联编。
2.override关键字可以指定重写基类中的虚函数的函数的成员(C++中的override只有检测防错的功能,与C#不同)。
3.final关键字可以指定不能在派生类中重写的虚函数①。 您还可以使用它指定无法继承的类②。
4.没有Sealed关键字。
举例:
virtual+override

class car
{
public:
	virtual void Weight()=0;
};
class truck : car
{
public:
	void Weight() override;
};

virtual+final情况①

struct Object{
    virtual void fun() = 0;
};

struct Base : public Object {
    void fun() final;   // 声明为final
};

struct Derived : public Base {
    void fun();     // 无法通过编译
};

virtual+final情况②

class Base final
{
};
 
// 错误,Derive不能从Base派生。
class Derive
        : public Base
{
};

Abstract(C#独有)
指示被修改内容的实现已丢失或不完整。 abstract 修饰符可用于类、方法、属性、索引和事件。 在类声明中使用 abstract 修饰符以指示某个类仅旨在作为其他类的基类。 标记为 abstract 的成员,或包含在抽象类中的成员,都必须由派生自抽象类的类来实现。
看起来是不是和Virtual很像,下面是他们的区别:
1.virtual修饰的方法必须有实现(哪怕是仅仅添加一对大括号),而abstract修饰的方法一定不能实现;
2.virtual可以被子类重写,而abstract必须被子类重写;
3.如果类成员被abstract修饰,则该类前必须添加abstract,因为只有抽象类才可以有抽象方法;
4.无法创建abstract类的实例,只能被继承无法实例化,比如: BaseTest2 base2 = new BaseTest2();将出现编译错误:抽象类或接口不能创建实例;
例如:

    abstract class TestAbstractSuper
    {
        public abstract void Init();
    }
    
    class TestAbstractSub:TestAbstractSuper
    {
        public override void Init()
        {
            Debug.WriteLine("这是子类重写的方法");
        }        
    }

Interface(C#独有)
可使用 interface 关键字定义接口。 接口包含类或结构可以实现的一组相关功能的定义。
例如,使用接口可以在类中包括来自多个源的行为。 该功能在 C# 中十分重要,因为该语言不支持类的多重继承。 此外,如果要模拟结构的继承,也必须使用接口,因为它们无法实际从另一个结构或类继承。
举例:

    public interface car
   {
       void Weight();
   }
    public class truck : car
    {
        public override void Weight()
        {
            Console.WriteLine("卡车车重10吨");
        }
    }

可以说和前面提到的Abstract很像了,下面是他们的异同:
相同点:
1、都可以被继承;
2、都不能被实例化;
3、都可以包含方法声明;
4、派生类必须实现未实现的方法。
区别:
1、抽象基类可以定义字段、属性、方法实现,接口只能定义属性、索引器、事件、和方法声明,不能包含字段;
2、抽象类是一个不完整的类,需要进一步细化,而接口是一个行为规范。微软的自定义接口总是后带able字段,证明其是表述一类“我能做。。。”;
3、接口可以被多重实现,抽象类只能被单一继承;
4、抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中;
5、抽象类是从一系列相关对象中抽象出来的概念,因此反映的是事物的内部共性;接口是为了满足外部调用而定义的一个功能约定, 因此反映的是事物的外部特性;
6、接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法;
7、接口可以用于支持回调,而继承并不具备这个特点;
8、抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的;
9、如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值