对象的概念
面向对象编程(Object-Oriented Programming OOP)是一种编程思维方式和编码架构。
抽象
- 将问题空间中的元素以及它们在解决方案空间的表示称作’对象‘(Object)。
- 万物皆对象。可以将对象想象成一种特殊的变量。它存储数据,但可以在你对其"发出请求"时执行本身的操作。理论上讲,你总是可以从要解决的问题身上抽象出概念性的组件,然后再程序中将其表示为一个对象。
- 程序是一组对象,通过消息传递来告知彼此该做什么。要请求调用一个对象的方法,你需要向该对象发送消息。
- 每个对象都有自己的存储空间,可容纳其他对象。或者说,通过封装现有对象,可制作出新型对象。所以,尽管对象的概念非常简单,但在程序中却可达到任意高的复杂程度。
- 每个对象都有一种类型。根据语法,每个对象都是某个“类”的一个“实例”。其中,“类”(Class)是“类型”(Type)的同义词。一个类最重要的特征就是“能将什么消息发给它?”。
- 同一类所有对象都能接收相同的消息。这实际是别有含义的一种说法,大家不久便能理解。由于类型为“圆”(Circle)的一个对象也属于类型为“形状”(Shape)的一个对象,所以一个圆完全能接收发送给"形状”的消息。这意味着可让程序代码统一指挥“形状”,令其自动控制所有符合“形状”描述的对象,其中自然包括“圆”。这一特性称为对象的“可替换性”,是OOP最重要的概念之一。
- 一个对象具有自己的状态,行为和标识。这意味着对象有自己的内部数据(提供状态)、方法(产生行为),并彼此区分(每个对象在内容中都有唯一的地址)。
接口
- 我们向对象发出的请求是通过它的“接口”(Interface)定义的,对象的“类型”或“类”则规定了它的接口形式。“类型”与“接口”的对应关系是面向对象程序设计的基础。
下面让我们以电灯泡为例:
Light lt = new Light(); lt.on();
- 在这个例子中,类型/类的名称是 Light,可向 Light 对象发出的请求包括打开 on、关闭 off、变得更明亮 brighten 或者变得更暗淡 dim。通过声明一个引用,如 lt 和 new 关键字,我们创建了一个 Light 类型的对象,再用等号将其赋给引用。为了向对象发送消息,我们使用句点符号 . 将 lt 和消息名称 on 连接起来。可以看出,使用一些预先定义好的类时,我们在程序里采用的代码是非常简单直观的。
服务提供
- 软件设计的基本原则是高内聚:每个组件的内部作用明确,功能紧密相关。在良好的面向对象设计中,每个对象功能单一且高效。这样的程序设计可以提高我们代码的复用性,同时也方便别人阅读和理解我们的代码。
封装
Java 有三个显式关键字来设置类中的访问权限:public(公开),private(私有)和protected(受保护)。这些访问修饰符决定了谁能使用它们修饰的方法、变量或类。
-
public(公开)表示任何人都可以访问和使用该元素;
-
private(私有)除了类本身和类内部的方法,外界无法直接访问该元素。private 是类和调用者之间的屏障。任何试图访问私有成员的行为都会报编译时错误;
-
protected(受保护)类似于 private,区别是子类(下一节就会引入继承的概念)可以访问 protected 的成员,但不能访问 private 成员;
-
default(默认)如果你不使用前面的三者,默认就是 default 访问权限。default 被称为包访问,因为该权限下的资源可以被同一包(库组件)中其他类的成员访问。
复用
- 代码和设计方案的复用性是面向对象程序设计的优点之一。我们可以通过重复使用某个类的对象来达到这种复用性。同时,我们也可以将一个类的对象作为另一个类的成员变量使用。新的类可以是由任意数量和任意类型的其他对象构成。这里涉及到“组合”和“聚合”的概念:
组合(Composition)经常用来表示“拥有”关系(has-a relationship)。例如,“汽车拥有引擎”。
聚合(Aggregation)动态的组合。
- 两个类生命周期不同步,则是聚合关系,生命周期同步就是组合关系。
继承
- 在继承过程中,若原始类(基类、超类或父类)发生了变化,修改过的’克隆’类(继承类或者子类)也会反映出这种变化。
- 基类包含派生自它的类型之间共享的所有特征和行为,创建基类表示思想的核心,从基类中派生出其他类型来表示实现核心的不同方式。
- 尽管继承有时意味着你要在接口中添加新方法(Java中用extends关键字表示继承) ,但并非总是如此。第二种也是更重要的区别派生类和基类的方法时改变现有基类方法的行为,这被称为覆盖(overriding)。要想覆盖一个方法,只需要再派生类中重新定义这个方法即可。
多态
- 多态是同一个行为具有多个不同表现形式或形态的能力。多态就是同一个接口,使用不同的实例而执行不同操作。
- 多态存在的三个必要条件:继承、重写、父类引用指向子类对象:Parent p = new Child();
- 发送消息给对象时,如果程序不知道接收的具体类型是什么,但最终执行是正确的,这就是对象的“多态性”(Polymorphism)。面向对象的程序设计语言是通过“动态绑定”的方式来实现对象的多态性的。编译器和运行时系统会负责对所有细节的控制。
单继承结构
- 在Java中最终基类就是Object,Java是单继承,C++是多继承。
对象创建与生命周期
- Java使用动态内存分配,每次创建对象时,使用new关键字构建该对象的动态实例,通常在堆上进行内存分配。
- 在栈内存中创建对象,编译器能够确定该对象的生命周期并自动销毁它;在堆内存中创建对象的话,编译器是不知道它的生命周期。在C++中必须以编程方式确定何时销毁对象,否则可能导致内存泄漏。Java的内存管理是建立在垃圾收集器上的,它能自动发现对象不再被使用并释放内存。
异常处理
- 异常(Exception)是一个从出错点抛出(throw)后被特定类型的异常处理程序捕获(catch)的一个对象。它不会干扰程序的正常运行,仅当程序出错的时候才被执行。
Shell基本操作
更改目录: cd <路径>
cd .. 移动到上级目录
pushd <路径> 记住来源的同时移动到其他目录,popd 返回来源
目录列举: ls 列举出当前目录下所有的文件和子目录名(不包含隐藏文件),
可以选择使用通配符 * 来缩小搜索范围。
示例(1): 列举所有以“.java”结尾的文件,输入 ls *.java (Windows: dir *.java)
示例(2): 列举所有以“F”开头,“.java”结尾的文件,输入ls F*.java (Windows: dir F*.java)
创建目录:
Mac/Linux 系统:mkdir
示例:mkdir books
Windows 系统:md
示例:md books
移除文件:
Mac/Linux 系统:rm
示例:rm somefile.java
Windows 系统:del
示例:del somefile.java
移除目录:
Mac/Linux 系统:rm -r
示例:rm -r books
Windows 系统:deltree
示例:deltree books
重复命令: !! 重复上条命令
示例:!n 重复倒数第n条命令
命令历史:
Mac/Linux 系统:history
Windows 系统:按 F7 键
文件解压:
Linux/Mac 都有命令行解压程序 unzip,你可以通过互联网为 Windows 安装命令行解压程序 unzip。
图形界面下(Windows 资源管理器,Mac Finder,Linux Nautilus 或其他等效软件)右键单击该文件,
在 Mac 上选择“open”,在 Linux 上选择“extract here”,或在 Windows 上选择“extract all…”。
要了解关于 shell 的更多信息,请在维基百科中搜索 Windows shell,Mac/Linux用户可搜索 bash shell。