(这是大体框架,以后部分知识细写)
1 抽象过程
所有编程语言都提供抽象机制。可以认为,人们能解决的问题的复杂性直接取决于抽象的类型和质量。
类型:指的是所抽象的是什么。
汇编语言是对底层机器语言的轻微抽象;
c、BASIC等命令式语言是对汇编语言的抽象;
这些语言虽然有很大的改进,但是他们做的主要抽象仍要求在解决问题时基于计算机的结构而不是问题的结构。这就要求程序员必须建立起机器模型(计算机)和实际问题的模型(一项业务)之间的关联。这是非常费力的,使得程序难编写,维护代价高昂。
另一种建模方式是针对特定问题进行建模,对于要解决的特定类型的问题来说,他们是非常不错的,但是一旦超出了特定领域,就显得力不从心了。
面向对象的方式通过向程序员提供表示问题空间中的元素的工具而更进一步。我们把问题空间(计算机)中的元素和在解空间中的表示成为“对象”。
Alan Kay总结了第一个成功的面向对象语言的五个特性:
1)万物皆对象(理论上讲,可以抽取问题的任何概念化构件,比如猫,建筑、服务)
2)程序是对象的集合,他们通过发送消息来告知彼此要做的。
3)每个对象都有自己的由其他对象所构成的存储(换句话说,可以通过创建包含现有对象的包来创建新类型对象)
4)每个对象都拥有自己的类型(每个对象都是某个类的实例,例如旺财是狗的实例)
5)某一特定类型的所有对象都可以接收同样的信息
简洁来说,对象具有状态、行为和标识。
2 类和对象
类:类是一个模板,它描述一类对象的行为和状态。(比如猫类狗类动物类)
对象:对象是类的一个实例,有状态和行为。例如,一条狗是一个对象,它的状态有:颜色、名字、品种;行为有:摇尾巴、叫、吃等。
现在让我们深入了解什么是对象。看看周围真实的世界,会发现身边有很多对象,车,狗,人等等。所有这些对象都有自己的状态和行为。拿一条狗来举例,它的状态有:名字、品种、颜色,行为有:叫、摇尾巴和跑。
对比现实对象和软件对象,它们之间十分相似。软件对象也有状态和行为。软件对象的状态就是属性,行为通过方法体现。在软件开发中,方法操作对象内部状态的改变,对象的相互调用也是通过方法来完成。
每种编程语言都有自己的操作内存中元素的对象,在java中,万物都是对象。注意,我们操作的是对象的引用:可以想象成电视机和遥控器,我们操作的是遥控器。
String s;
创建了一个引用,也就是遥控,但是他现在不能操作电视。
存储的地方有:
1)寄存器: 最快的存储区,它位于处理器内部,人们不能直接控制,也不能在程序中感觉到寄存器的存在。
2)堆栈:位于RAM,通过堆栈指针可以从处理器获得直接支持,靠指针移动来分配或释放内存,这是快速有效的方法。创建程序时,java系统必须知道存储在堆栈内的所有项的生命周期。(引用存储在堆栈)
3)堆:一种通用的内存池,存放所有的java对象。不需要知道存储的数据的生命周期。但是用堆进行分配和清理会比用堆栈需要更多时间。
4)常量存储:直接放在程序法代码内部,这样做是安全的,因为它们永远也不会改变,存放在ROM。
5)非RAM存储:如果数据完全活在程序之外,它可以不受任何程序的控制。比如流对象和持久化对象。
有的对象比较小、简单,所以存储在堆里往往不是很好,我们把他们存在堆里就可以了,这种对象我们把他们叫做基本类型。
boolean\char\byte\short\int\long\float\double\void
3 提供部分服务
当正在开发或者试图理解一个程序设计时,最好的方法之一就是将对象想象为一个服务的提供者。
因为程序本身一定会向用户提供服务,它将调用其他对象的服务来实现这一目的,我们的目标就是去创建能够提供理想的服务来解决问题的一系列对象。遇到需求请问一下自己:“如果我将问题从表象中抽取出来,什么样的对象可以解决我的问题?”他们看起来是什么样子?他们能够提供哪些服务?他们需要哪些对象才能履行他们的义务?如此持续的这样做,我们会发现“这个对象好像挺简单”。
将对象想象为一个服务的提供者,有助于提高内聚性。
人们设计对象面临的一个问题是:将过多的功能放到了一个对象中。在良好的面向对象设计中,每个对象都可以良好的完成一个任务,但是它并不试图做更多的事。
4 隐藏
将开发人员分为类创建者和客户端程序员是非常科学的。客户端程序员的目标是收集各种用来实现快速应用开发的类。而类的创建者的目标是构建类,这种类只向客户端程序员暴露必须的部分,隐藏其他的部分。被隐藏的部分通常是对象内部比较脆弱的部分,他们很容易被粗心或不知内情的客户端程序员毁坏,所以被隐藏(保护)起来。
java用三个关键字设定边界:
public 对任何人可用。
private除了创建者和对象内部方法,其他任何人都不能访问,这就像是和客户端程序员的一堵墙,或者说是程序的保护伞。
protected和private类似,区别是继承的类可以访问。
无关键字为包权限,可以访问同一个包的其他类成员。
5 复用
一旦类被创建并测试完,他就应该被视为有用的代码单元。代码复用是面向对象程序设计语言所提供的最了不起的优点之一。
两种复用方法:
1)组合:把已知类放入新的类中,新的类可以由任意数量、类型的其它类组成。就像拿零件组装汽车。
注意:组合带来了极大的灵活性。由于继承在面向对象中如此重要,所以经常被高度强调,很多程序员因此忽视了组合,处处都继承,有时候,这样是不科学的,不符合常理的,会导致过分复杂的设计。在建立新类时,应优先考虑组合。
2)继承:我们以现有的类为基础,添加和修改副本来创建新类。就是继承。经典例子就是图形:每一个图形都有尺寸、颜色、位置等,都可以被绘制、擦出、移动、着色等。在此基础上,可以有圆形、正方形、三角形等。他们每一个图形都具有图形类的特点,并有属于自己的特点。
注意:继承是否应该只继承基类的属性方法,而不添加新的属性和方法呢?
如果这样做,就意味着新类和基类是完全相同的数据类型,因为它们具有完全相同的接口。这可以被视作纯粹替代,这是一种处理继承的理想方式。这种关系为is a的关系,比如“圆形是一个(is a)形状”。
有时必须添加新的接口元素。这样其实并不完美,因为基类无法访问新的方法。这种情况是is like a(像是),比如空调,房子具备了让你控制冷气的接口和制冷空调,后来你用了能制冷制热的新设备替换了空调,但是房子的设计就是只涉及==设计了制冷接口,所以尽管新对象接口扩展了,但是现有系统对新街口一无所知。
6 多态
多态:同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果。
比如你是一个酒神,对酒情有独钟。某日回家发现桌上有几个杯子里面都装了白酒,从外面看我们是不可能知道这是些什么酒,只有喝了之后才能够猜出来是何种酒。你一喝,这是剑南春、再喝这是五粮液、再喝这是酒鬼酒….在这里我们可以描述成如下:
酒 a = 剑南春
酒 b = 五粮液
酒 c = 酒鬼酒
…
这里所表现的的就是多态。剑南春、五粮液、酒鬼酒都是酒的子类,我们只是通过酒这一个父类就能够引用不同的子类,这就是多态——我们只有在运行的时候才会知道引用变量所指向的具体实例对象。
注意:我们或许都写过这样的方法:它接收一个基类参数,比如酒,然后不管这个酒是哪种酒,都能执行对应的方法。
这些代码不是:“如果是剑南春,就这样做,是五粮液,就那样做。。。。。。”
而是:“你是酒,我知道你是酒,我知道你可以做一些事,那么,就去做吧”
7 单根继承
在面向对象编程中,有一个很瞩目的问题:是否所有类最终都继承自单一的类。
在java中,答案是:是的。
而c++则不是。
具体利弊以后会解释
8 容器
如果不知道在解决问题时需要多少对象,或者存活多久,那就不可能知道怎么存储他们了。
容器(也称为集合)在任何需要的时候都可以扩充自己以容纳所有的东西。
好的OOP语言都有属于自己的容器,比如c++的STL,Object Pascal的VCL,java也一样有大量容器,有list、set、map等。
9 生命期
10 错误
11 并发