对象导论
面向对象方式通过向程序员提供表示问题空间中的元素的工具二更进了一步。我们将问题空间中的元素及其在解空间中的表示成为对象。这种思想的实质是:程序可以通过添加新类型的对象使自身适用于某个特定问题。
接口
每个对象都只能满足某些请求,这些请求由对象的接口所定义,决定接口的便是类型。接口确定了对某一对象所能发出的请求。
向某个对象“发送消息”(产生请求),这个对象便知道此消息的目的,然后执行对应的程序代码。
每个对象都提供服务
将对象看做是服务提供者还有一个附带的好处:它有助于提高对象的内聚性。
隐藏具体实现
Java用三个关键字在类的内部设定边界:public、private、protected。类创建者使用这些关键字来隐藏具体实现,意味着类创建者可以任意修改被隐藏的部分,而不用担心对其他人造成影响;同时,客户端程序员也无法访问。
public:紧随其后的元素对任何人都是可用的
private:除类创建者和类型的内部方法之外的任何人都不能访问的元素
protected:继承的类可以访问protected成员,但不能访问private成员
复用具体实现
新的类可以由任意数量、任意类型的其他对象以任意可以实现新的类中想要的功能的方式所组成。因为是在使用现有的类合成新的类,所以这种概念被称为组合。如果组合是动态发生的,那么它通常被成为聚合。
继承
当继承现有类型时,也就创造了新的类型。这个新的类型不仅包括现有类型的所有成员(尽管private成员被隐藏了起来,并且不可访问),更重要的是它复制了基类的接口。
有两种方法可以使基类与导出类产生差异:
直接在导出类中添加新的方法
改变现有基类的方法的行为,这被称之为覆盖那个方法
“是一个”和“像是一个”
是一个(is-a):只覆盖基类的方法,而不添加新方法
像是一个(is-like-a):在导出类型中添加新的接口元素
伴随多态的可互换对象
面向对象程序设计的最重要的秘诀:编译器不可能产生传统意义上的函数调用。一个非面向对象编程的编译器产生的函数调用会一起所谓的前期绑定,这意味着编译器将产生一个具体函数名字的调用,而运行时将这个调用解析到将要被执行的代码的绝对地址。
面向对象程序设计语言使用了后期绑定的概念。当向对象发送消息时,被调用的代码直到运行时才能确定。
在某些语言中,必须明确地声明希望某个方法具备后期绑定属性所带来的灵活性(C++使用virtual关键字实现)。在这些语言中,方法默认情况下不是动态绑定的。而在Java中,动态绑定是默认行为,不需要添加额外的关键字来实现多态。
单根继承结构
在Java 中,所有类都最终继承自单一基类(Object)。
在单根继承结构中所有对象都具有一个共用接口,所以它们归根到底都是相同的基本类型。
单根继承结构保证所有对象都具备某些功能。
单根继承结构使垃圾回收器的实现变得容易得多。因为,所有对象都保证具有其类型信息。
对象的创建和生命期
C++为了追求最大的执行速度,对象的存储空间和生命周期可以在编写程序时确定,这可以通过将对象置于堆栈(有时被称为自动变量或限域变量)或静态储存区域内来实现。这种方式将存储空间分配和释放置于优先考虑的位置,某些情况下这样控制非常有价值,但是也牺牲了灵活性,因为必须在编写程序时知道对象确切的数量、生命周期和类型。
另一种控制对象生命周期的方式,是在被称为堆的内存池中动态地创建对象。这种方式,直到运行时才知道需要多少对象、它们的生命周期和具体类型。如果需要一个对象,可以在需要的时刻直接在堆栈中创建。因为储存空间是在运行时被动态管理的,所以需要大量的时间在堆中分配存储空间,这可能远远大于在堆栈中创建存储空间的时间。在堆栈中创建存储空间和释放存储空间通常各需要一条汇编指令即可,分别对应将栈顶指针向下移动和将栈顶指针向上移动。
Java完全采用动态内存分配方式。每当想要创建新对象时,就要使用new关键字来构建此对象的动态实例。
异常处理
Java一开始就内置了异常处理,且强制必须使用它。
并发编程
在计算机编程中有一个基本概念,就是在同一时刻处理多个任务的思想。
有时中断对于处理时间性强的任务是必需的,但是对于大量其他问题,我们只是想把问题切分成多个可以独立运行的部分,从而提高程序的响应能力。在程序中,这些彼此独立运行的部分称之为线程,上述概念被称为并发。
通常,线程只是一种为单一处理器分配执行时间的手段。但是如果操作系统支持多处理器,那么每个任务都可以被指派给不同的处理器,并且它们可以真正的并行执行。在语言级别上,多线程所带来的便利之一便是程序员不用再操心机器上是有多个处理器还是只有一个处理器。由于程序在逻辑上被分为线程,所以如果机器拥有多个处理器,那么程序不需要特殊调整也能执行得更快。
并发有一个隐患:共享资源。
Java的并发是内置于语言中的。
最后更新于
这有帮助吗?