今天开始的这个礼拜,回补java基本知识,再次回炉学习。
1 , 程序员必须建立起在机器模型和设计待解问题的模型之间的关联。建立这种关联是费力的,而且不属于编程语言所固有的功能,使得编程难以编写,并且维护代价高昂,同时也产生了作为副产物的整个“编程方法”行业。
2,对象具有状态,行为和标识。状态:每个对象可以拥有内部数据(它给出了对象的状态);方法:它们产生的行为;并且每个对象都可以和其他对象区分开来,具体就是每个对象在内存中都存在唯一的地址。
3,每个对象都有一个接口。创建抽象数据类型(类)是面向对象程序设计的基本概念之一。类描述了具有相同特性(数据元素)和行为(功能)的对象集合。接口确定了对某一特定对象所能发出的请求。在程序中必须要有满足这些请求的代码,这就是实现。向某个对象发送消息,其实就是产生某个请求,而请求和方法关联,自然就进行了方法的调用。
4,每个对象都提供服务。我们需要构建一个合理的对象来解决我们面临的问题。所以如何将问题分解为对象是我们需要思考的问题。高内聚是软件设计的基本要求之一,这意味着一个软件构件的各个方面“组合”的很好。
5, 被隐藏的具体实现。将程序开发人员按照角色分为“创建者”(那些创建新数据类型的程序员)和“客户端程序员”(那些在应用中使用数据类型的消费者)是大有裨益的。一个类被隐藏的部分意味着创建者可以任意的修改它而不用担心对其他人造成影响。被隐藏的部分也是对象内部脆弱的部分,很容易被粗心的或者不知内情的客户端程序员所毁坏,因此将实现隐藏起来可以减少程序的bug。
访问控制的第一个存在原因是让客户端程序员无法触及他们不该触及的部分。第二个存在的原因是允许库设计者可以改变类内部的工作方式而不用担心影响到客户端程序员。
6,复用具体实现。代码复用是面向对象程序设计语言所提供的最了不起的优点之一。组合(composition)和聚合(aggregation)。组合常被视为“has-a”(拥有)关系。组合和聚合的区别是大多数人头痛的问题。聚合更为松散,它是“如果组合是动态发生的,那么它就是聚合”。可能还是很抽象,这我不得不举个《大话》里面的例子。组合,就好比大雁的翅膀和大雁的关系,大雁如果没了,大雁的翅膀肯定也就没了。聚合,就是大雁和雁群的关系,一个大雁它可以随时的加入到一个雁群里面,它还可以离开。关系就松散多了。
还有,能用组合关系就尽量用组合关系,而不是继承。
7,继承。为什么要有继承?因为我们想偷懒,当我们实现了一个类的时候,另外一个跟它类似的类,我们还是要重新定义,我们多么渴望通过拷贝现有的类然后改改就能够定义新的类。于是就有了“继承”。继承有个父类(基类),然后就是子类(导出类)。子类继承父类,父类的改动也会反映到子类。
当继承现有类型时,也就创造了新的类型。这个新的类型不仅包含了现有类型的所有成员(尽管private成员被隐藏起来了,而且不能访问),而且更为重要的是它复制了基类的接口。也就是说,所有可以发送给基类对象的消息都可以发送给导出类的对象。导出类和基类对接口的不同实现,即覆盖(Overriding)。导出类如果添加了新的接口,基类是无法访问的。这种关系虽然是继承,但是不是纯粹替代。叫"is-like-a",而不是“is-a"。
8,伴随多态的可互换对象。在处理类型的层次结构时候,经常把一个对象不当做它所属的特定类型来对待,而是将其当做基类的对象来对待。这使得我们可以编写出不依赖特定类型的代码。泛化(Generic)。添加新的类,并不需要更改调用它的地方,都统一采用基类来看待,来传递消息,却能够根据所传递的对象自身类型执行不同的实现。
那么如何实现这个机制的呢?这就引出了”前期绑定“和”后期绑定“。后期绑定是在程序运行的时候才能够确定它所调用的代码。(C++中采用virtual关键字来实现的,而Java中默认就打开)。把导出类看做是它的基类的过程叫做向上转型(Upcasting)
9,单根继承。C++ 和Java最争论的一个重要问题就是单继承和多继承的问题。这个问题各有各的好处,不过建议就是,如果你公司的代码以前有很多C代码,那么C++ 是比较好的;如果你的项目是从头开始,建议用Java。
10,容器。C++中,容器是标准C++ 类库的一部分,经常被称为标准模板库(Standard Template Library,STL)。Java中,具有满足不同需要的各种容器。在Java SE5之前,之前,容器的对象只有Java中通用类型:Object,这样进了容器,就只知道是Object类型,取出来的时候类型消失了,所以你要自己显式的向下转型,就是将Object转为你的类型,但有个问题,除非你确切的知道放进去的是什么,否则很容易发生放进去的是苹果,结果你非得说人家是凤梨,然后用凤梨在转人家,这样是会发生异常的。。
在Java SE5之后,Java容器增加了参数化类型,Java叫它范型。eg. ArrayList<Shap> shapes=new ArrayList<Shap>();这样就限定了我这个容器,只能够装Shape类型(当然,你懂得它的导出类也就是)。
11,对象的创建和生命期。C++认为效率控制是最重要的议题,所以它给了程序员选择的权利。为了追求最大的执行速度,对象的存储空间和生命期可以在编写程序的时候确定。Java是采用了动态内存分配的方式,在堆(Heap)内存池中动态创建对象。Java具有垃圾回收机制,当没有人引用这个对象的时候,对象会被释放。
12,异常处理:处理错误。异常发生的时候是不可以忽略的,你必须进行相应的处理,你可以在里面选择进一步校正,使得程序再次回到正规,或者你可以输出调试信息。而在C和C++中,经常用返回错误码来表示错误。但是,调用者却可以忽略你的错误码。。。所以,异常是具有强制性的。
13,并发编程。多线程问题。
14,Java和Internet。