mirror of
https://github.com/LingCoder/OnJava8.git
synced 2026-09-03 21:32:48 +08:00
update
This commit is contained in:
@@ -35,7 +35,7 @@ Grady Booch 提供了对对象更简洁的描述:一个对象具有自己的
|
||||
## 接口
|
||||
|
||||
亚里士多德(*Aristotle*)或许是认真研究“类型”概念的第一人,他曾谈及“鱼类和鸟类”的问题。是世界首例面向对象语言Simula-67 中,第一次用到了这样的一个概念:
|
||||
所有对象——尽管各有特色——都属于某一系列对象的一部分,这些对象具有通用的特征和行为。在Simula-67 中,首次用到了class 这个关键字,它为程序引入了一个全新的类型(class 和 type 通常可互换使用,有些人进行了进一步的区分,他们强调“类型”决定了接口,而“类”是那个接口的一种特殊实现方式)。
|
||||
所有对象——尽管各有特色——都属于某一系列对象的一部分,这些对象具有通用的特征和行为。在Simula-67 中,首次用到了`class` 这个关键字,它为程序引入了一个全新的类型(`class` 和 type 通常可互换使用,有些人进行了进一步的区分,他们强调“类型”决定了接口,而“类”是那个接口的一种特殊实现方式)。
|
||||
|
||||
Simula 是一个很好的例子。正如这个名字所暗示的,它的作用是“模拟”(Simulate)象“银行出纳员”这
|
||||
样的经典问题。在这个例子里,我们有一系列出纳员、客户、帐号以及交易等。每类成员(元素)都具有一
|
||||
@@ -44,7 +44,7 @@ Simula 是一个很好的例子。正如这个名字所暗示的,它的作用
|
||||
体分别表示出纳员、客户、帐号以及交易。这个实体便是“对象”,而且每个对象都隶属一个特定的“类”,那个类具有自己的通用特征与行为。
|
||||
|
||||
因此,在面向对象的程序设计中,尽管我们真正要做的是新建各种各样的数据“类型”(Type),但几乎所
|
||||
有面向对象的程序设计语言都采用了“class”关键字。当您看到“type”这个字的时候,请同时想到“class”;反之亦然。
|
||||
有面向对象的程序设计语言都采用了`class`关键字。当您看到“type”这个字的时候,请同时想到`class`;反之亦然。
|
||||
|
||||
创建好一个类后,可根据情况生成许多对象。随后,可将那些对象作为要解决问题中存在的元素进行处理。事实上,当我们进行面向对象的程序设计时,面临的最大一项挑战性就是:如何在“问题空间”(问题实际存
|
||||
在的地方)的元素与“方案空间”(对实际问题进行建模的地方,如计算机)的元素之间建立理想的“一对
|
||||
@@ -75,18 +75,24 @@ lt.on();
|
||||
|
||||
那么问题来了:“当我可以随时调用这些方法时,我该选择哪个来解决我的问题呢?”例如,假设你正在开发一个记事本程序。您可能会想在屏幕输入一个预定义的记事本对象,一个用于检测不同类型打印机并执行打印的对象。也许这些对象中的部分已存在。那么对于那些没有的对象,他们应该会是什么样子呢?这些对象提供哪些服务,以及履行其义务需要哪些对象?
|
||||
|
||||
分解问题的良好方式是将其抽象成一组方法。高内聚是软件设计的基本原则:每个组件各自的作用清晰集中。经常有人将太多功能塞进一个对象中。例如,在支票打印模块中,你可能需要一个同时读取格式又能打印种类的对象。正确的做法是提供三个或更多对象。一个对象检查所有布局的目录;一个对象或一组对象可以是一个通用的打印界面,它知道所有不同类型的打印机;第三个对象使用其他两个服务来完成任务。因此,每个对象都提供了一组紧密的服务。在良好的面向对象设计中,每个对象功能单一,效果显著。这样可以提高代码的复用性。将对象作为服务提供者处理不仅有利于我们的程序设计,同时也方便别人阅读和理解我们的代码。只有先让人知道你提供什么服务,别人才有可能将其应用到其他程序色设计中。
|
||||
分解问题的良好方式是将其抽象成一组服务。高内聚是软件设计的基本原则:每个组件各自的作用清晰集中。经常有人将太多功能塞进一个对象中。例如,在支票打印模块中,你可能需要一个同时读取格式又能打印种类的对象。正确的做法是提供三个或更多对象。一个对象检查所有布局的目录;一个对象或一组对象可以是一个通用的打印界面,它知道所有不同类型的打印机;第三个对象使用其他两个服务来完成任务。因此,每个对象都提供了一组紧密的服务。在良好的面向对象设计中,每个对象功能单一,效果显著。这样的设计可以提高代码的复用性有利于我们的程序设计,同时也方便别人阅读和理解我们的代码。只有让人知道你提供什么服务,别人才有可能将其应用到其他程序色设计中。
|
||||
|
||||
|
||||
## 封装
|
||||
|
||||
|
||||
我们可以将编程的侧重领域区分为研发和应用。应用程序员调用前者构建的基础工具类来快速开发。研发程序员构建一个类,该类仅向应用程序员公开必要的内容,并保护其他所有内容。隐藏技术实现的细节可以有效避免错误的使用和改变,因此隐藏实现可以减少程序错误。双方有着各自的工作侧重点,彼此尊重。当您创建库时,您与客户端程序员建立了关系,客户端程序员也是程序员,但是通过使用您的库来组装应用程序,可能是为了构建更大的库。如果研发提供的工具暴露了内部所有内容,那么有些规则就不好被遵守。你无法保证应用程序员不去改变它。即使你不喜欢应用程序员直接操作你的某些方法,但是只要有没有访问控制,你就没办法阻止别人怎么做。
|
||||
我们可以将编程的侧重领域区分为类创建者和客户端程序员。客户端程序员调用类创建者构建的基础工具类来快速开发。类创建者构建一个类,该类仅向客户端程序员公开必要的内容,并保护其他所有内容。隐藏技术实现的细节,避免程序被错误的使用和改变,减少程序错误。双方有着各自的工作侧重点,彼此尊重。当创建者创建库时,与客户端程序员建立了关系,客户端程序员通过使用创建者的库来组装应用程序或者构建更大的库。如果创建者提供的工具库暴露了工具本身的所有内容,那么有些规则就不好被遵守。你无法保证客户端程序员不去改变它。即使你不喜欢客户端程序员直接操作你的工具中的某些方法,但是只要没有访问控制,你就没办法阻止这种做法。
|
||||
|
||||
因此,访问控制的第一个原因是让为了让应用程序员不要触摸他们不应该触摸的部分。(请注意,这也是一个哲学决策。部分编程语言认为如果程序员有需要,则应该让他们访问细节部分。);第二个原因是使库设计者不影响应用程序员使用库情况下更新完善类。例如,您可以以简单的方式实现特定的类以简化开发,然后发现您必须重写它以使其运行得更快。如果界面和实现明确分开并受到保护,您可以轻松完成此任务。Java 有三个显式关键字来设置类中的边界:public,private和protected。这些访问说明符确定谁可以使用后面的定义。public意味着每个人都可以使用该元素。private意味着没有人可以访问该元素,除了您,该类型的创建者,该类型的内部方法。私人是你和客户程序员之间的砖墙。任何试图访问私有成员的人都会收到编译时错误。受保护的行为类似于私有,但是继承类可以访问受保护的成员,但不能访问私有成员。很快就会引入继承。Java还具有“默认”访问权限,如果您不使用上述说明符之一,它将发挥作用。这通常称为包访问,因为类可以访问同一包(库组件)中其他类的成员,但在包外,这些相同的成员看起来是私有的。
|
||||
因此,使用访问控制的原因:
|
||||
|
||||
1. 让客户端程序员不要触摸他们不应该触摸的部分。(请注意,这也是一个哲学决策。部分编程语言认为如果程序员有需要,则应该让他们访问细节部分。);
|
||||
|
||||
2. 使库创建者在不影响客户端程序员使用库情况下更新完善工具库。例如,你以粗陋的方式开发了开发额一个类来简化任务,后来你发现必须重写它以使其运行得更快。如果应用程序接口和实现部分明确分开并受到保护,您可以轻松完成改造。
|
||||
|
||||
Java 有三个显式关键字来设置类中的访问权限:`public`(公开),`private`(私有)和`protected`(受保护)。这些修饰符确定谁可以使用后面的定义。`public` 表示任何人都可以访问和使用该元素;`private` 说明除了类本身,外界无法直接访问该元素和内部方法。`private`是你和客户程序员之间的砖墙。任何试图访问私有成员的人都会收到编译时错误。`protected`的行为类似于`private`,区别是继承类可以访问`protected`的成员,但不能访问`private`成员。下一节就会引入继承的概念。Java 还具有`default`(默认)访问权限,如果你不使用前面的三者,默认就是`default`访问权限。`default`被称之为包访问,因为类可以访问同一包(库组件)中其他类的成员。
|
||||
|
||||
|
||||
## 复用
|
||||
## 复用性
|
||||
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user