【Professional C# 读书笔记】(二)-----语言基础:继承,运算符,类型转换的杂七杂八
Posted on 2010-09-01 23:18 Chrisplus 阅读(188) 评论(0) 编辑 收藏 举报不同于c++,没有多重继承,这是一件让人感到开心的事……至少我是这样认为的(多重继承把代码搞得不易于理解和调试,当然,多重继承也有他的优势,比如更加的灵活)。于是和JAVA一样,当我们想多重的沿袭某某时,我们使用接口继承,而普遍的继承法方式则被称为实现继承。
· 在实现继承中,有关于虚方法:virtual
· 按照c++的传统,而是java的,一个方法在默认的情况下不是虚拟的。注意,virtual只对于实例方法有作用!~
· c#要求在派生类重写基类的方法时,需要使用 override 显式的声明!这里,MS给出的理由是 在编程中,有“很多时候”,我们会因为一个小小失误导致 方法的签名与基类不同,从而无法重写(一个新的方法被声明)。额……这不是一个好理由,有了ItelliSence,这个应该不是问题吧……除非给出一个更为合理的解释,否则我认为这不是一个好的改变!
· new关键字在隐藏方法上的使用,这里的new并不是运算符……而是一个关键字。其目的是解决如下的问题:如果在派生类和基类中声明了两个签名的方法,而这个方法没有 virtual(基类)或者 override(派生类)修饰,那么~基类的方法将会被隐藏!就是白写了~是白写了,白写了,写了,了……如果愿意,我们最好重命名~当然这是在二者完成完全不相关的功能的前提下!如果不这么做,我们可以使用new关键字,让他们不相关……;
说实话,对于基于这种目的而产生的语法,在我没在实际中遇到,我永远不会相信他的重要性,就比如new关键字,或许他的全部意义就在于,对于客户,保证在你的新旧程序版本中调用方法的无痕……或许吧!
· base的使用,相当于 java的 super;在c#中,我们没有用fuction = 0的形式去声明一个纯虚函数,于是abstract 抽象长生了,实现了几乎相同的功能。 sealed关键字,相当于final
· 关于接口,interface,在我的理解的范围之内,我是这样来概括接口的:一种有着相同“通信”协议 的对象的 组织形式。
根据对象不同特性,对象就会有很多中组织形式:比如,所有的对象都可以看作是object的实例……比如有些对象是派生自同一个类的实例。
对象之间的“通信”靠的是他们的方法,当他们的(一部分)方法有些相同的制式的时候,我们就可以在通信这个维度上来组织他们,例子先略掉。
· 在编写不安全代码的时候-----比如,把一个长类型(32位)强制转化为短类型(16位,8位),数据可能会溢出,那么我们使用checked 运算符,CLR会执行检查,如果溢出,会抛出异常。uncheck是禁止溢出检查的,在编译的时候,给定编译参数/checked,全部检查~当然,会跳过unchecked检查
· is 运算符,对象与类的兼容性检查;as运算符,显示的类型转化,但是用成不成功的问题,我觉得如果是有效的as,应该是从基类到派生类的转化……至少这个是一定成功的。
· 可空类型,int? a = null 有点像三态门……多了一种unknow状态,有几个比较规则:
在比较可空类型是,只要一个是null,结果就是false
还有一个狗血的空结合运算符,?? 确实够狗血的!
· 类型转换:什么情况下可以隐式的转换?不会造成数据的丢失的情况下~一般是可以进行隐式的转换的。可空类型可隐式的转换为可空,非可空->可空,可空不能隐士的到非可空,因为null没法判定……
在可能有数据丢失的情况下,可以是使用显示的类型转换……
· boxing与unboxing 。装箱用于描述把一个 值类型 转换为 一个引用类型……拆箱刚好相反。
关于装箱的使用,让我想起了cpp中的&,引用,在c#没有了显式的声明一个值类型的引用或者指针~so,装箱的意义产生了。写到这里,我又联想起前面的学习笔记中提到的ref 和out输出参数,当时我写到,二者的实现方式应该是相同,证据之一是不能用out,ref作为函数签名。到这里,我在进一步,ref out的实现方式应该是boxing……
显而易见,拆箱的时候可能有溢出~谁知道箱子里面会不会i有弹簧蛇……
· 对象的相等比较:那么大致可以分为深度和浅度两种喽……很纠结于混乱的东西~我倒是觉得object中的几个方法除了那个virtual不提,其他两个没啥营养……
· 下面就是传说中的语法糖 sytax suger~运算符重载……不过在c#中。我可不认为这仅仅是糖这么简单。
在c#中所有的运算符重载都需要声明为public与static,目的是脱离实例与类相关的。这也到省去了c++operator是不是成员函数的烦恼。而且说实话,我觉得friend的存在,本身就是违背OO思想的。这个简化与严格化,不错~
对于比较运算符,需要成对的重载,比如,重载了==就也要重载!=
· 自定义数据类型转换:这也是一种运算符重载,所以~要遵循上述的原则。在声明的是有 implicit 与 explicit 之分
值得关注的是 多重数据类型转换,起大致的意义在于,编译器了可以在已知的类型中进行自适应的转换。
比如我们定义了如下的隐式转换
view plaincopy to clipboardprint?public static implicit operator int(MyClass mc) { //something I will do } public static implicit operator int(MyClass mc)
{
//something I will do
} view plaincopy to clipboardprint?MyClass test = new MyClass(); int i = 5 + MyClass; MyClass test = new MyClass();
int i = 5 + MyClass;
这样是可以的,(编译器?)应该会选择一条精确度损失最小的路线(这是我估计的判定规则)来 进行转换,因为这里只有一条,即:MyClass->float->int
Ok~这一篇 Over