《Java编程思想 4th》第一章对象导论上

《Java编程思想 4th》第一章对象导论上,第1张

《Java编程思想 4th》第一章对象导论上

我们之所以将自然界分解,组织成各种概念,并按其含义分类,主要是因为我们是整个口语交流社会共同遵守的协定的参与者,这个协定以语言的形式固定下来…除非赞成这个协定中规定的有关语言信息的组织和分类,否则我们根本无法交谈。
–Benjamin Lee Whorf

1.1 抽象过程

人们所能解决的问题的复杂性直接取决于抽象的类型和质量。面向对象方式通过向程序员提供表示问题空间中的元素的工具而更进一步。这种表示方式非常通用,使得程序员不会受限于任何特定类型的问题。
我们将问题空间中的元素及其在解的空间中的表示为“对象”(你还需要一些无法类比为问题空间元素的对象)。这种思想的实质是:程序可以通过添加新类型的对象使自身适用于某个特定的问题。
我们描述问题的 = 代码构建对象
面向对象语言的五个基本特性,这些特性表现了一种纯粹的面向对象程序设计方式:

万物皆可对象程序使对象的集合,它们通过发送消息来告知彼此所要做的每个对象都有自己的组成,这个组成也可以是由其他对象、类型构成每个对象都拥有其类型(Class)某一特定类型的所有对象可以接收同样的信息

对象具有状态、行为和标识。 即类的属性值,方法和属性。

1.2 每个对象都有个接口

类描述了具有相同特性(数据元素)和行为(功能)的对象集合,所以类在计算机语言中就是一组多类型数据和方法的组合。程序员可以对类进行修改(增删查改类的特性或行为)使之更符合实际解决问题。
接口确定了对某一特定对象所能发出的请求(程序员决定类,类决定接口,接口决定类能做的事)。

1.3 每个对象都提供服务

程序本身将向用户提供服务,它将通过调用其他对象(类的具体化实例化)提供的服务来实现这一目标。
将对象看作是服务提供者还有一个好处:它将有助于提高对象的内聚性。高内聚是软件设计的基本质量要求之一,这意味着一个软件架构的各个方面“组合”得很好(软件各个功能之间相互作用发挥出1+1>2的功效/或简化代码)。
将对象作为服务提供者来看待是一件伟大的简化工具,这不仅在设计过程中非常有用,而且当其他人试图理解你的代码或重新利用某个对象/某个对象的某个方法时,如果他们看出来这个对象所能提供的服务价值(功能),它会时调整对象以适应其涉及的过程变得非常简单。

1.4 被隐藏的具体实现

将程序开发人员按照角色分为类创建者(创新新类)和客户端程序员(应用创建新类型的类消费者)是大有裨益的。客户端程序员的目标是收集各种类用于快速应用开发,类创建者的目标是构建类,这种类指向客户端程序员暴露必须的部分,而隐藏其他部分,保证安全,减少bug。
在任何相互关系中,具有关系所涉及的各方都遵守的边界是十分重要的,要实现访问控制。
Java用三个关键字在类的内部设定边界:public、private、protected。public任何人能够使用,private表只有类创建者和类内部方法可以访问,protected表示类创建者、类内部方法、继承类可以访问。
Java还有一种默认的访问权限,当没有使用前面三个关键字时,它将发挥作用。默认=包访问权限,包内各类可以访问该默认元素。

1.5 复用具体实现

一旦类被创建并完成测试,纳闷它应该代表一个有用的可以被重复使用的代码单元(理想情况下)。代码服用时面向对象程序设计语言的最大优点之一。
最简单地服用某个类的方式就是直接使用该类的一个对象,此外也可以将某个类置于一个新类中。新的类可以有任意数量、类型的其他对象以任意方式所组合(composition)起来。
在考虑创建新类时,首先应考虑组合而非继承。

1.6 继承

在现实中,猫是一个类,橘猫、蓝猫等也是一个类但这个类是猫的大类下属。在计算机世界中同样如此,这种关系叫继承,非实际世界中的继承,二是更为广泛抽象的类的继承。
当继承现有类型时,也就创造了新的类型。这个新的类型不仅包括现有类型的所有成员,而且更重要的是它复制了基类(父类)的接口(方法)。子类可以使用继承父类的接口,也可以重写(overriding)该接口,也可以另外添加新方法,以符合实际要解决问题。

1.6.1 “是一个”和“像是一个”的关系

is-a和is-like-a的关系。对于继承可能会引发争论:继承应该只覆盖基类的方法(而不添加新方法)吗?如果这样做,就意味着子类和父类时完全相同的类型。结果是子类可以完全替代父类,这可以被视为纯粹替代/替代原则。
父类和子类的关系是“is-a”的关系。

1.7 伴随多态的可互换对象

通过导出新的子类而轻松拓展设计的能力,是对改动进行封装的基本方式之一。这种能力可以极大地改善我们的设计,同时降低软件维护成本。泛化的概念。
但是在继承的特性下,程序大多通过泛化来简化工作提高效率,如果用圆形、正方形等代表几何图形,用企鹅、鸭代替动物使用,那么编译器在编译时是不可能知道应该执行那一段代码。如要绘画几何图形,但是绘画三角形、正方形的方法都不一样。
为了解决这个问题,OOP使用了后期绑定的策略。被调用的、泛化的代码直到运行时才会被确定。编译器确保被调用的方法存在,并对调用参数和返回值执行类型检查,但是并不知道将被执行的确切代码。
为了成功执行后期绑定,java使用一段特殊的代码来替代绝对地址调用。这段代码使用在对象中存储的信息来计算方法体的地址(第8章详述)。这样根据着一小段代码的内容,每一个对象都可以具有不同的行为表现。当向一个对象发送消息时,该对象能够知道对这条消息该做什么。
这个方法可以跟任何Shape类型的对象进行沟通。

void doSomething(Shape shape){
	shape.draw();
}

circle和triangle和line类继承了shape类型,下面对类进行实例化并使用上面创建的方法。

Circle circle = new Circle();
Triangle triangle = new Triangle();
Line line = new Line();
doSomething(circle);
doSomething(triangle );
doSomething(line );

当java编译器在编译doSomething时是并不知道line类等的,三个子类在使用doSomething方法时会被向上转型为shape类(调用时),这样dosomething能够正确接收子类的消息,但同时使用的方法是正确的子类的方法。这就是OOP语言多态的强大特性。当向一个对象发送消息时,即使涉及向上转型,该对象也知道要执行什么任务。

欢迎分享,转载请注明来源:内存溢出

原文地址: https://outofmemory.cn/zaji/5706927.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存