• 设为首页
  • 点击收藏
  • 手机版
    手机扫一扫访问
    迪恩网络手机版
  • 关注官方公众号
    微信扫一扫关注
    公众号

C#继承

原作者: [db:作者] 来自: [db:来源] 收藏 邀请

在编程中也沿用了继承的概念,在面向对象编程中,如C++和C#中都有类的继承。 继承(加上封装和多态性)是面向对象的编程的三个主要特性(也称为“支柱”)之一。 继承用于创建可重用、扩展和修改在其他类中定义的行为的新类。 其成员被继承的类称为“基类”,继承这些成员的类称为“派生类”。 派生类只能有一个直接基类。 但是,继承是可传递的。 如果 ClassB 派生出 ClassC,ClassA 派生出 ClassB,则 ClassC 会继承 ClassB 和 ClassA 中声明的成员。

v写在前面

无论是其他社区还是园子里,关于继承类的帖子或者文章已经可以说是数不胜数了,关于继承类的话题也是旧调重弹了。写这篇博文只是为了加深一下自己对继承的理解,所谓读书百遍其意自见嘛。这篇博文中部分内容来自我的读书(C#高级编程从开始接触C#到现在我已经是第五遍读了,每次读都有不一样的收获。)笔记,和一些自己的理解。

vC#继承

1.实现继承 

如果要声明派生自另一个类的一个类,就可以使用下面的语法:

    class LearningClass : BasicClass
    {
    }

如果类(或结构)也派生自接口,则用逗号分隔列表中的基类和接口:

  class LearningClass : BasicClass, BasicInterface, BasicInterface2
    {
    }

对于结构,语法如下:

    struct LearningStruct : BasicInterface, BasicInterface2
    {
    }
使用结构的一个限制是结构不支持继承,但每个结 构都自动派生自system,ValueType。实际上还应更仔细一些:不能编码实现类型层次的结构,但结 构可以实现接口。换言之,结构并不支持实现继承,但支持接口继承。事实上,定义结构和类可以 总结为:
  • 结构总是派生自system。ValueType,它们还可以派生自任意多个接口。
  • 类总是派生自用户选择的另一个类,它们还可以派生自任意多个接口。

在类定义中没有指定基类,钭编译器就假定system.Object是基类。因此下面的两段代码生成相同的结果:

  class LearningClass : Object
    {
    }
    class LearningClass
    {
    }

2.虚方法virtual: 

有时候我们继承一个基类的某些方法希望能重新定义这个方法,我们可以把一个基类函数声明virtual,就可以在任何派生类中重写这个函数:

public class BasicClass
    {
        public virtual string GetMessage()
        {
            return "Basic class message";
        }
    }

C#中虚函数的概念与标准00P的概念相同:可以在派生类中重写虚函数。在调用方法时,会调用该类对象的合适方法。在C#中,函数在默认情况下不是虚拟的,但(除了构造函数以外)可以显 式地声明为virtual。这遵循C++的方式,即从性能的角度来看,除非显式指定,否则函数就不是虚 拟的。而在Java中,所有的函数都是虚拟的。但C#的语法与C++的语法不同,因为C#要求在派生 类的函数重写另一个函数时,要使用override关键字显式声明:

    class LearningClass : BasicClass
    {
        public override string GetMessage()
        {
            return "Learning class message";
        }
    }

重写方法的语法避免了C++中很容易发生的潜在运行错误:当派生类的方法签名无意中与基类 版本略有差别时,该方法就不能重写基类的方法:在C#中,这会出现一个编译错误,因为编译器会 认为函数已标记为override,但没有重写其基类的方法。

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

3.隐藏方法: 

如果签名相同的方法在基类和派生类中都进行了声明,但该方法没有分别声明为virtual和 override,派生类方法就会隐藏基类方法。

在大多数清况下,是要重写方法,而不是隐藏方法,因为隐藏方法会造成对于给定类的实例调用 错误方法的危险。但是,如下面的例子所示,C#语法可以确保开发人员在编译时收到这个潜在错误的 警告,从而使隐藏方弦【如果这确实是用户的本匐更加安全。这也是类库开发人员得到的版本方面的 · 好处

此时,编译时系统会发出警告。在C#中,要隐藏一个方法应使用new关键字声明,如下所示:

  public class LearningClass : BasicClass
    {
        public new string GetMessage()
        {
            return "Learning class message";
        }
    }

4.调用函数的基类版本: 

C#有一种特殊的语法用于从派生类中调用方法的基类版本:base.()。例如,假定 派生类中的一个方法要返回基类的方法20%的返回值,就可以使用下面的语法:

    public class BasicClass
    {
        public virtual float GetPrice()
        {
            return 1.5f;
        }
    }
    public class LearningClass : BasicClass
    {
        public float GetPrice()
        {
            return base.GetPrice() * 0.2f;
        }
    }

ps:可以使用base.()语法调用基类中的任何方法,不必从同一个方法的重载 中调用它。

5.抽象类和抽象函数: 

C#允许把类和函数声明为abstract。抽象类不能实例化,而抽象函数不能直接实现,必须在非抽 象的派生类中重写。显然,抽象函数本身也是虚拟的(尽管也不需要提供virtual关键字,实际上,如 果提供了该关键字,就会产生一个语法错误。如果类包含抽象函数,则该类也是抽象的,也必须声 明为抽象的:

    public abstract class BasicClass
    {
        public abstract float GetPrice();
    }
    public class LearningClass : BasicClass
    {
        public override float GetPrice()
        {
            return 0.2f;
        }
    }

6.密封类和密封方法: 

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

在把类或方法标记为sealed时,最可能的情形是:如果要对库、类或自己编写的其他类作用域 之外的类或方法进行操作,则重写某些功能会导致代码混乱。也可以因商业原因把类或方法标记为 sealed,以防第三方以违反授权协议的方式扩展该类。但一般情况下,在把类或成员标记为sealed 时要小心,因为这么做会严重限制它的使用方式。即使认为它不能对继承自一个类或重写类的某个 成员发挥作用,仍有可能在将来的某个时刻,有人会遇到我们没有预料到的情形,此时这么做就很 有用。.NET基类库大量使用了密封类,使希望从这些类中派生出自己的类的第三方开发人员无法访 问这些类。例如,string就是一个密封类。

把方法声明为sealed也可以实现类似的目的,但很少这么做。

7.修饰符: 

C#共有五种访问修饰符:public、private、protected、internal、protected internal。作用范围如下表:

访问修饰符 说明
public 公有访问。不受任何限制。
private 私有访问。只限于本类成员访问,子类,实例都不能访问。
protected 保护访问。只限于本类和子类访问,实例不能访问。
internal 内部访问。只限于本项目内访问,其他不能访问。
protected internal 内部保护访问。只限于本项目或是子类访问,其他不能访问

C#成员类型的可修饰及默认修饰符如下表:

成员类型 默认修饰符 可被修饰符
enum public none
class private public、protected、internal、private、
protected internal
interface public none
struct private public、internal、private

修饰符可以应用于类型的成员,而且有不同的用途:

修饰符 应用于 说明
new 函数成员 成员用相同的签名隐藏继承的成员
static 所有成员 成员不作用于类的具体实例
virtual 仅函数成员 成员可以由派生类重写
abstract 仅函数成员 虚拟成员定义了成员的签名,但没有提供实例代码
override 仅函数成员 成员重写了继承的虚拟或抽象成员
sealed 类,方法和属性 对于类,不能继承自密封类。对于属性和方法,成员重写已继承的虚拟成员,但任何派生类中的任何成员都不能重写该成员。该修饰符必须与override一起使用
extern 仅静态[DllImport]方法 成员在外部用另一种语言实现




作  者:请叫我头头哥
出  处:http://www.cnblogs.com/toutou/
关于作者:专注于基础平台的项目开发。如有问题或建议,请多多赐教!
版权声明:本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接。
特此声明:所有评论和私信都会在第一时间回复。也欢迎园子的大大们指正错误,共同进步。或者直接私信
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角推荐一下。您的鼓励是作者坚持原创和持续写作的最大动力!


鲜花

握手

雷人

路过

鸡蛋
该文章已有0人参与评论

请发表评论

全部评论

专题导读
上一篇:
C#API大全发布时间:2022-07-10
下一篇:
C#DateTime月第一天和最后一天取法发布时间:2022-07-10
热门推荐
阅读排行榜

扫描微信二维码

查看手机版网站

随时了解更新最新资讯

139-2527-9053

在线客服(服务时间 9:00~18:00)

在线QQ客服
地址:深圳市南山区西丽大学城创智工业园
电邮:jeky_zhao#qq.com
移动电话:139-2527-9053

Powered by 互联科技 X3.4© 2001-2213 极客世界.|Sitemap