圈点C#的继承

本文详细介绍了 C# 中的继承与接口概念,包括实现继承与接口继承的区别,多重继承的特点,以及抽象类、密封类等高级特性。同时,还深入探讨了接口的声明与实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于我这种从C++中转过来的人来说,已经相当熟悉C++中的继承特性了。刚开始接触C#的继承时,写的继承类的代码基本就和C++的一样。所以记录以下东西来加深对C#继承的。对于C++来说,用的最多的是实现继承,但是对于C#而言,还有一个接口继承。先来说说实现继承和接口继承。

 

实现继承:便是一个类型派生于一个基类型,拥有该基类型的多有成员字段和函数。在实现继承中,派生类型的每个函数采用基类型的实现代码,除非在派生类型的定义中指定重写该函数的实现代码。在需要给现有的类型添加功能,或许多相关的类型共享一组重要的公共功能时,这种类型的继承是非常有效的。

 

接口继承:表示一个类型只继承了函数的签名,没有继承任何实现代码。在需要指定该类型具有某些可用的特性时,最好使用这种类型的继承。

 

关于多重继承

 

C#中不支持多重实现继承。即一个类只能派生于一个基类,但是可以继承于多个接口!

 

一、实现继承

 

例如下面就是一个实现继承,相信对于很多熟悉C++的程序员来说是很熟悉的:

 

public class CFather

        {

            public CFather()

            {

                Console.WriteLine("我是基类CFather");

            }

            //其他成员

        }

        public class CSon : CFather

        {

            public CSon()

            {

                Console.WriteLine("我是CFather的派生类!");

            }

            //其他成员

     }

 

注意:C#不支持私有继承,因此基类名上没有publicprivate限定符!

如果类也派生于接口,则用逗号分隔开基类和接口:

public class CSon : CFather, Interface1, Interface2

         {

            //成员实现

      }

 

虚方法

把一个基类函数声明为virtual,该函数就可以在任何派生类中重写了。这同样也适用于属性。

 

C#中可以在派生类中重写虚函数。在调用方法时,会调用对象类型的何时方法。在C#中,函数默认情况下不是虚拟的,但(除了构造函数以外)可以显式的声明为virtual。但是C#要求在派生类的函数重写另一个函数时,要用override关键字显式声明。下面来看一个例子:

 

        public class CFather

        {

            public CFather()

            {

                Console.WriteLine("我是基类CFather");

            }

            virtual public void Fuction()

            {

                Console.WriteLine("Fuction in CFather!");

            }

        }

        public class CSon : CFather

        {

            public CSon()

            {

                Console.WriteLine("我是CFather的派生类!");

            }

            public override void Fuction()

            {

                Console.WriteLine("Function in CSon!");

            }

        }

 

Main()函数中:

 

            CFather a = new CFather();

            CSon b = new CSon();

            a.Fuction();

            b.Fuction();

运行结果如下:

 

我是基类CFather

我是基类CFather

我是CFather的派生类!

Fuction in CFather!

Function in CSon!

 

派生类的构造函数

 

构造函数的调用顺序是先调用System.Object,再按照层次节后由上向下进行,直到到达编译器要实例化的类为止。还要注意在这个过程中,每个构造函数都初始化自己的类中的字段。

 

构造函数的执行顺序,总是最先调用基类的构造函数。也就是说,派生类的构造函数可以在执行过程中调用基类方法、属性和其他成员,因为基类已经构造出来了,其字段也初始化了。

 

可以看到有两个“我是基类CFather”!这是因为派生类的对象的实例化必须从基类往下一步步的进行,这和C++的是一样的!

 

注意:成员字段和静态函数都不能声明为virtual,因为这个概念只对类中的实力函数成员有意义。

 

调用函数的基类版本

 

C#有一种特殊的语法用于从派生类中调用方法的基类版本:base.<MethodName>()

 

抽象类和抽象函数

 

C#允许把类和函数声明为abstract,抽象类不能实例化,而抽象函数没有执行代码,必须在非抽象的派生类中重写。显然,抽象函数也是虚拟的(但也不需要提供virtual关键字,实际上如果提供了该关键字,就会产生一个语法错误)。如果类包含抽象函数,该类将也是抽象的,也必须声明为抽象的。当然抽象类里也可以声明变量:

 

        abstract class CAbstract

        {

            public abstract void Fuction1(int a);

        }

        class CSon : CAbstract

        {

            public CSon()

            {

            }

            public override void Fuction1(int a)

            {

                Console.WriteLine("{0}", a);

            }

        }

 

密封类和密封方法

 

C#允许把类和方法声明为sealed。对于类来说,这表示不能继承该类;对于方法来说,这表示不能重写该方法。例如:

        sealed class ClassA

        {

            //方法属性等……

        }

        class ClassB : ClassA//这样的继承是错误的!

        {

            //方法属性等……

        }

 

二、修饰符

 

可见性修饰符:

 

 

其他修饰符:

 

C#中的接口

接口是把隐式公共方法和属性组合起来,以封装特定功能的一个集合。一旦定义了接口,就可以在类中实现它。这样,类就可以支持接口所制定的所有属性和成员、

 

注意,接口不能单独存在。不能实例化一个类那样实例化接口,而且接口的成员都是公共的。另外,接口不能包含其实现其成员的任何代码,而只能定义成员本身。实现过程必须在实现接口的类中实现。接口不能包含字段、构造函数、析构函数、静态成员或常量!

 

一个类可以支持多个接口,多个类也可以支持相同的接口。所以接口的概念让用户和其他开发人员更容易理解其他人的代码。例如有一些代码使用一个带某接口的对象。假定不使用这个对象的其他属性和方法,就可以用领个对象代替这个对象。

接口的声明

    //声明一个接口IA

    interface IA

    {

        int Max_int(int a, int b);

}

 

接口的实现

 

由于接口必须在类中实现,所以下面我们定义一个CInstance类:

 

        class CInstance : IA

        {

            public CInstance()

            {

            }

            public int Max_int(int a, int b)

            {

                if (a >= b)

                    return a;

                else

                    return b;

            }

        }

 

如果一个类继承于类又继承于接口,那么就用逗号来区分他们。接口的继承是可以实现多重继承的。

注意:对接口的继承一定要在类中实现接口中的所有方法!不如不会通过编译的!

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值