C#面向对象,如何在代码编写时使用多态?

本文适合有一定经验的程序员阅读。本文假定读者你是懂面向对象的封装继承多态的。

文章的例子,以常见的“美食”为例来演示。文章的代码以中文演示,是为了让您看得方便,生产中,建议英文。

 

多态

它的规矩是简单而易见的,通常使用abstract和virtual来标记。所以,在C#中,您只需要根据这2个关键字,便可以认出它是多态。

多态,可以针对方法、属性、事件、索引器使用。

以美食为例,我们知道,美食存在多种做法,我们的业务会划分中西餐,而中餐和西餐的做法是不同的。所以,美食的类应该根据需求封装如下:

由于美食存在中餐和西餐的制作方法不同,所以,我们需要给方法Make()打上virtual关键字,以便根据实际情况给出不一样的做法:

好的,这是一个很简单的例子,对于懂面向对象特性或者仅懂abstract及virtual关键字的读者来说,这小儿科。

 

那么:您知道什么情况下该加virtual关键字,什么情况下不加吗?

这是窗体Winform组件Control的基类Component,我想问下为什么给Site加了virtual,而Container却不加?

为什么Dispose()不加virtual,而Dispose(bool)却加了virtual?

virtual的用法是简单的,每个人都会,加上它即可以。用它可以很好的进行程序扩展。但加了virtual是有性能开销的,比不加的开销要大些。为了更好的追求程序设计,您不应该随意添加virtual。

 

程序设计的最小、最少原则

这不是一个教程里,至少不是上了台面的原则。就是说,我们的程序设计在做任何设计的时候,都应往最小、最少的方向考虑,这适用于很多方面。

比如,一个方法体的代码行数,超出30行,您就要思考是否耦合了2种或者更多的业务逻辑。

比如,通篇都是public,您是否确定真的全部都应该public,就没有需要internal、private的吗?

比如,判断条件(if/else)过多的时候,我是否没有进行良好的设计,没有做好抽象?

比如,当我的设计类,被别人继承后,我的方法或者属性,是否需要开放修改,还是过多开放?

等等等等,很多情况,都是您需要考虑的。

 

多态,什么情况下加virtual,什么情况下不加?

回过头来看Winform的Component类的设计,它开放了Site属性的virtual,那么代表它在设计时,一定有他们的考量,该属性存在有可能要让子类修改的必要,所以加virtual。而Container,可能仅需要传达数据,它是通过其它地方传递过来的,无法提供修改可能,所以禁止重写。

对于Dispose来说,它用于资源释放,而释放通常仅需要提供调用即可,因为它的重写可能性存在于针对本类的非托管资源来操作,所以,它要设计为保护方法是虚的。您还需要知道一点:public的Dispose()方法,将调用protected的Dispose(bool)方法,知道这点很重要。也就是说,它变相的使用了virtual。

 

加virtual的一些原则参考:

1.除非你有明确的理由,确信本类是可以扩展的,并且方法、属性、索引器、事件等有被重写的必要理由。才添加virtual关键字。

2.多态的范围,应尽可能缩小,如果有必要,可以将其虚化范围限制为protected,而不必要一定是public。然后public的公共成员,应调用protected的受保护成员来实现扩展。

3.所有密封类sealed无需多态。

 

举例子:

像ABP(AspNet Boilerplate),它所有的服务方法(Service)均要求声明为virtual,以便获得事务。这是它的理由。您也需要理由。

 

祝您用餐愉快。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值