发表于: 2017-08-04 00:54:24

17 1197


问题在下面,师兄。

一 今天做的事情

5.7 多态

  书上看到了引用类型之间的转换只能在具有继承关系的两个类型之间进行,引用类型?不就是String么。

  书上还介绍了一个运算符用来判断是否可以成功转换,真逗,做出判断的是人,计算机只需要执行就行了。后来再一想。可能是转换的判断不好判定,或者转换的对象不能确定等等。“存在即合理”,instanceof运算符可以判断是否可以成功转换这个记下了。书上说用instanceof运算符可以提高程序的健壮性,健壮性这个单词听到了好多次,但是一直不知道具体是什么意思。今天上网查了一下,健壮性是指程序对不符合要求的输入数据的处理能力。就像之前的五子棋程序中对重棋的处理。重棋是不符合要求的输入数据,我用了一些算法来解决这个问题,在用户输入重棋时会有提示,这样就提高了程序的健壮性。

  书上还专门花了一小节的内容来阐述instanceof的用法,看来很重要。在这一小节中我了解到Object是所有类的父类。

  若前面的对象所属的类不是后面的类或者子类,编译就会报错。这样就感觉书上写的自相矛盾了:前面说“它(指instanceof运算符)用于判断前面的对象是否是后面的类,或者其子类、实现类的实例。如果是,则返回ture.否则返回false。”而在接下来的程序里,书上举了这么个例子,还有注释:

  String a = "Hello" ;

  // String类于Math类没有继承关系,所以下面代码编译无法通过

  System.out.println("字符串是否是Math类的实例:"

+ (a instanceof Math));

  先不说按照本书的程序写作的特点,编译有问题的代码行要注释掉这个问题,我们说主要的问题:instanceof这个运算符。在网上查了一下,然后编写了程序验证了一下:

  谢谢程序,替我问候了作者。实际上我很早就想问候作者了,在我发现书上一个接着一个的错误之后。写书的作者也许是个技术大牛,我发现的书上的错误有常见的语法错误,还有一些像这个,不算错误,但是由于表述不清会误导读者的问题。说回正题,通过网上的一些例子(网上的很多例子也是鱼龙混杂,这样的也好意思写博客。prt是什么?哪个关键字?用这个就能打印YES和NO?http://blog.csdn.net/u014581901/article/details/60137773,不过就只有这个人的程序用instanceof勉强输出了false,其他网上的例子都没有输出flase),instanceof前面的对象必须属于后面的类或者字类有继承关系,不属于则报错;若前面的对象所属的类是后面的类的父类或者间接父类,那么输出false;若前面的对象所属的类是后面类的子类则输出true。概括一句话,instanceof只能向上检查,从所属的类开始一直到object这个所有类的父类,属于就返回true,不属于就返回flase。

  书上最后说了instanceof和type是一对好基友,instanceof先判断能不能强制转换,若可以则用type进行强制转换。听上去很有道理,那么期待在程序中用到这对好基友吧。

5.8 继承与组合

  5.8.1 使用继承的注意点

  在这一小节中书上介绍了使用继承的一个缺点:破坏了父类的封装。封装是隐藏父类内部的对象方法,只提供setter和getter这两种方法来访问修改父类,而继承的子类可以访问父类的成员,书上说了一堆,说明了一个问题:利用子类可以修改父类,在某些人手上,修改就可以变成恶意篡改。为了防止这种事情发生,书上用了两个关键字,private和final。后者还没有学到。另外书上还说了尽量不要在父类构造器中写一些可以被子类重写的方法。我没有写过很多程序,感触不深,记住它就行了。感觉看完书上的例子就不会再用到它了。因为这个条件看上去似乎很难满足:首先,要有两个类,一个子类一个父类,这个条件容易满足;然后子类中必须要有和父类中一样方法名的方法,构成方法的重写;最关键的来了:在父类的构造器中还要调用到这个能被子类重写的方法。同时满足三个条件还是感觉挺难的。不过书上就生搬硬凑出来一个例子,苦口婆心地就是让我们理解。看到这我又有点感谢作者了。

  在刚才打字的时候把重写打成重载,然后在脑子里下意识地想了一下这两者的联系和区别。结果是:没有逻辑上的联系,只是这两个动词都有重这个字,就像我叫蔡国强,有个歌手叫蔡国庆一样。我们之间的联系只是名字的前两个字一样,其他的我是个准程序员,他是个歌手而已。重载是说的在同一个类中多个方法的名称一样但是参数列表不同这样就构成了重载,而重写在子类和父类之间,子类和父类中有同名的方法就是重写。

  这一节作者还说了何时使用继承关系是一个难以把握的问题,同上面的问题,感触不深,还是因为程序写的少。

  5.6.2 利用组合实现复用

  复用我理解为重复使用(引用、调用)。

  书上提供了两个例子,第一个例子平淡无奇,定义的子类对象直接调用父类方法就实现了复用;第二个例子是子类不再继承父类(为了书写方便我还是接着叫他们子类父类)而是在子类中直接定义父类对象,通过它来调用父类方法。最后作者还用了UML图来表示例子中所用到的类。UML在第二章介绍过,通过图表来表示分析软件程序。

  什么时候使用继承什么时候使用组合呢?抛开内存空间问题不谈(毕竟我们需要先解决问题,然后再优化代码算法等等问题,让问题的执行者计算机更容易地解决问题),当一个类(继承中叫父类,组合中叫旧类)中的对象或者方法已经满足不了我们的需求,这时候我们就需要继承;子类中可以使用父类的构造器对象方法,而且还可以有自己的构造器对象方法;而原有的类中的对象方法能满足我们的需求,我们就不必继承,使用组合就行了。关于继承和组合我理解到了就是不知道用什么样的文字语言来概括描述它,就连书上也是用的“总之,继承要表达的是一种“是(is-a)”的关系,而组合表达的是“有(is-a)”的关系”。我和书上的表达都不够好,希望我在实际编写很多程序之后能真正领悟到继承和组合的含义。

  到现在为止,面对对象的三大特征:封装继承多态基本概念已经了解了,接下来就需要在编程中用代码来更深层次地理解这三个特性。

5.9 初始化块

  这小节介绍了类中的第四个成员(之前有构造器、变量和方法):舒适化块。说白了就是在类中存在的一个代码块。编译时系统会在编译构造器之前编译它,所以叫初始化块。这让我想到了PLC中S7-300中也有初始化块:OB100,在这里一般只有一个语句,那就是复位所有的继电器线圈。

  自己写的程序结果运行出来自己都不能解释。人世间的痛苦莫过如此吧。结果为什么是3,12呢?为什么不是3,13呢?程序的执行过程我想应该是1-2-3-4,而按照结果来推算真正的执行过程是1-2-4-3。为什么会这样?

  无论构造器代码在初始化代码块之前还是之后,结果总为3,也就是构造器是最后执行的。

  在写这个程序的时候出了一个错误:

  我只是想定义一个变量,然后再修改它,有什么错误?为什么会报错?也许是当局者迷吧,我没有看出这有什么错。

  一个小程序能出现两个问题,这个小程序也算物有所值了。

  初始化块说白了就是个块,不能接受参数,因此在初始化块里我们可以放置无需参数的初始化语句,需要参数的就放在构造器中。乍一看初始化代码块没什么用,但是在构造器多的时候,如果多个构造器里有相同的无需参数的初始化语句,那么初始化的好处就体现出来了,也就是书上说的提高了程序的复用性。我对复用性的理解是,代码不写第二遍。这应该就是复用性的最高境界了吧。

  在这节的最后讲了静态初始化块,这个块比普通的初始化块限制行,其他的就没什么。

二 明天做的事情

完成第5章练习,开始第六章

  



返回列表 返回列表
评论

    分享到