4.1 Introduction to Object-Oriented Programming
主要介绍OOP的特点和其优势。
4.1.1 Classes
class就是类,是object也就是具体对象的模板或者说蓝图。当创建了一个对象,可以说是创建了这个类的一个实例(instance)。
封装(Encapsulation)是使用对象的一个关键概念,意思就是对object使用者隐藏一些实现的细节。
4.1.2 Objects
对象有三个重要的特点:表现(behavior),状态(state)和身份(identity)。
表现由object的方法(methods)来决定。
4.1.3 Identifying Classes
主要讲怎么阅读一个class,注意名词和动词。
4.1.4 Relationships between Classes
类与类之间最常见的3种关系:依赖(dependency)、聚合(aggregation)、继承(inheritance)。
另外还提到了UML图,用来表示类之间的关系。
4.2 Using Predefined Classes
4.2.1 Objects and Object Variables
Java用构造器(constructor)来新建类的实例。
构造器实际上也是类里面的一个方法,与类名同名。
需要注意的是,对象变量事实上并不是拥有一个对象,而是引用一个对象。
4.2.2 The LocalDate Class of the Java Library
这个类使用的是工厂模式。
LocalDate newYearsEve = LocalDate.of(1999, 12, 31);
int year = newYearsEve.getYear(); // 1999
int month = newYearsEve.getMonthValue(); // 12
int day = newYearsEve.getDayOfMonth(); // 31
4.2.3 Mutator and Accessor Methods
有些方法,并不改变作为参数的类,而是把处理结果作为一个新的类返回。这种函数在String类里面很常见。
而有些方法就会改变类的值或者状态。这种方法也很常见。
那些只获得值,不改变状态的方法叫做accessor method。
4.3 Defining Your Own Classes
4.3.1 An Employee Class
最简单的class形式:
class ClassName
{
field1
field2
. . .
constructor1
constructor2
. . .
method1
method2
. . .
}
这一小节使用了一个例子。
4.3.2 Use of Multiple Source Files
编译一个类,里面的内部类也会自动被编译。
4.3.3 Dissecting the Employee Class
提到了public和private两个关键字。public是无限制,其他的类也能访问;private就是只在这个类的方法才能访问。
4.3.4 First Steps with Constructors
构造函数只能和new一起使用。一个类可以有多个构造方法。构造方法可以接受任意个变量,没有返回值。
4.3.5 Implicit and Explicit Parameters
两种参数,implicit是指在使用方法之前就已经定义好的变量,explicit则是函数接受的变量。
4.3.6 Benefits of Encapsulation
解释封装的好处,就是数据的安全性。
4.3.7 Class-Based Access Privileges
类里面的方法能够访问类里面的private数据,因此可以传出去。
4.3.8 Private Methods
方法也可以是private的。
4.3.9 Final Instance Fields
final的参数必须在构造器完成构造的时候完成赋值,因为此后就不允许修改了。
4.4 Static Fields and Methods
4.4.1 Static Fields
static修饰的变量,在该类里面就只有一个该变量,也就是说所有的该类的对象都共享这个变量。
可以理解为类变量,class variable.
4.4.2 Static Constants
static修饰的常量,可以在不实例化类的时候直接使用className.staticConstant,例如Math.PI。一般和public final一起使用。
4.4.3 Static Methods
和静态常量有点类似,也是可以不用实例来调用的,例如Math.pow(x,y)。有点类似于Python的class method。
有两个场合适合用静态方法:所有变量都由外部提供,或者只需要静态变量。
4.4.4 Factory Methods
有时候可以用工厂方法来新建对象,因为这样可以创造不同名字满足要求的对象,还可以返回不同的对象,更加灵活。
4.4.5 The main Method
main这个方法就是静态方法,因此可以在构造对象之前调用。
4.5 Method Parameters
变量有传值和传引用两种,Java都是传值。
例:
double percent = 10;
harry.raiseSalary(percent);
不管第二句是怎么个情况,执行之后percent的值不会改变,因为它是基础数据类型,把自己的值传进去,复制给函数的参数,之后发生了什么不会影响它的值。
对象的引用是传值的。
4.6 Object Construction
4.6.1 Overloading
允许多个方法有同一个名字,而有不同的变量组合。
4.6.2 Default Field Initialization
默认会设置没有赋值的变量。不建议靠这个来初始化。
4.6.3 The Constructor with No Arguments
有些类可以有一个无参数的构造器,里面可以进行一些默认设置。
4.6.4 Explicit Field Initialization
在构造函数之前就可以对一些参数进行初始化,这样可以减少出现错误的可能性。
4.6.5 Parameter Names
命名可以在变量真实含义之前加a,m,x来取名。
4.6.6 Calling Another Constructor
假如一个构造器的第一句带有this,可以调用其他的构造器。
这样的话,可以只写一个通用构造器,然后在其他的构造器中调用这个通用的。
4.6.7 Initialization Blocks
Java还有一个初始化机制,就是赋值语句块,用大括号包起来放在构造器之前,会在构造完成的时候执行。
初始化的顺序:
- 所有数据初始化为默认值。
- 按照出现顺序,所有初始化代码块被执行。
- 构造器执行。
4.6.8 Object Destruction and the finalize Method
Java并没有支持销毁对象的方法,因为有垃圾回收机制。不过可以写一个finalize方法,会在回收前被调用。同时最好不要依赖这个方法,而是自己写一个处理方法,然后当用完一个对象的时候调用。
4.7 Packages
使用包的主要目的之一就是防止名字重复。
4.7.1 Class Importation
使用import方法来导入包。
4.7.2 Static Imports
例如import static java.lang.System.*;可以直接使用这个包下的静态方法和变量,不需要前缀。
4.7.3 Addition of a Class into a Package
把想要加入的包名放在第一行。
4.7.4 Package Scope
默认的default访问权限是包内可以访问。
4.8 The Class Path
讲一些路径设置。
4.9 Documentation Comments
讲了文档附注的一些写法和规则。
4.10 Class Design Hints
一些建议和提示:
- 保持数据私有。遵从封装原则,只暴露给外界想要提供的方法。
- 总是进行数据初始化。
- 一个类里面不要使用太多基础数据类。