在线时间:8:00-16:00
迪恩网络APP
随时随地掌握行业动态
扫描二维码
关注迪恩网络微信公众号
v写在前面无论是其他社区还是园子里,关于继承类的帖子或者文章已经可以说是数不胜数了,关于继承类的话题也是旧调重弹了。写这篇博文只是为了加深一下自己对继承的理解,所谓读书百遍其意自见嘛。这篇博文中部分内容来自我的读书(C#高级编程从开始接触C#到现在我已经是第五遍读了,每次读都有不一样的收获。)笔记,和一些自己的理解。 vC#继承1.实现继承如果要声明派生自另一个类的一个类,就可以使用下面的语法: class LearningClass : BasicClass { } 如果类(或结构)也派生自接口,则用逗号分隔列表中的基类和接口: class LearningClass : BasicClass, BasicInterface, BasicInterface2 { } 对于结构,语法如下: struct LearningStruct : BasicInterface, BasicInterface2 { } 使用结构的一个限制是结构不支持继承,但每个结 构都自动派生自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。作用范围如下表:
C#成员类型的可修饰及默认修饰符如下表:
修饰符可以应用于类型的成员,而且有不同的用途:
|
请发表评论