基本概念
类:构造对象的模板和蓝图。
封装:有时称为数据隐藏。是处理对象的一个重要概念。从形式上看,封装就是将数据和行为组合在一个包中,并对对象的使用者隐藏具体的实现方式。
实例字段:对象中的数据。
方法:操作数据的过程。
继承:通过扩展一个类来建立另外一个类的过程称为继承。
知识点
构造器
构造器与类同名。在构造类的对象时,构造器会运行,从而将实例字段初始化为所希望的初始状态。
构造器与其他方法有一个重要不同。构造器总是结合new运算符来调用。不能对一个已经存在的对象调用构造器来达到重新设置实例字段的目的。
每个类可以有一个以上的构造器。
构造器可以有0个,1个或多个参数。
构造器没有返回值。
使用NULL值引用
一个对象变量包含一个对象的引用,或者包含一个特殊值null,后者表示没有引用任何对象。
如果对null值应用一个方法,会产生一个NullPointerException异常。
这是一个很严重的错误,类似于“索引越界”异常。如果你的程序没有“捕获”异常,程序就会终止。正常情况下,程序并不捕获这些异常,而是依赖于程序员从一开始就不要带来异常。
隐式参数与显示参数
方法中的参数通常分为隐式参数与显示参数,隐式参数是出现在方法名前的类类型的对象。显示参数是位于方法名后面括号中的数值。
可用关键词this指示隐式参数,可以将实例字段与局部变量明显地区分开。
final实例字段
可以将实例字段定义为final。这样的字段必须在构造对象时初始化。也就是说,必须确保在每一个构造器执行之后,这个字段的值已经设置,并且以后不能再修改这个字段。
静态方法
静态方法是不在对象上执行的方法。可以认为静态方法是没有this参数的方法。
以下两种方法可以使用静态方法:
(1)方法不需要访问对象状态,因为它需要的所有参数都通过显示参数提供。
(2)方法只需要访问类的静态字段。
注:建议使用类名而不是对象来调用静态方法。
方法参数
按值调用:表示方法接受的是调用者提供的值。
按引用调用:表示方法接收的是调用者提供的变量地址。
方法可以修改按引用传递的变量的值,而不能修改按值传递的变量的值。
java程序设计语言总是采用按值调用。也就是说,方法得到的是所有参数值的一个副本。
方法不能修改基本数据类型的参数。
方法可以改变对象参数的状态。
方法不能让一个对象参数引用一个新的对象。
重载
如果多个方法有相同的名字,不同的参数,便出现了重载。编译器必须挑出具体调用哪个方法。它用各个方法首部中的参数类型与特定方法调用中所使用的值类型进行匹配,来选出正确的方法。查找匹配的过程被称为重载解析。
构造器的具体处理步骤
(1)如果构造器的第一行调用了另一个构造器,则基于所提供的参数执行第二个构造器。
(2)否则,
a)所有数据字段初始化为其默认值(0,false,null)
b)按照在类声明中出现的顺序,执行所有字段初始化方法和初始化块。
(3)执行构造器主体代码。
类设计技巧
(1)一定要保证数据私有。
这是最重要的;绝对不要破坏封装性。有时候,可能需要编写一个访问器方法或更改器方法,但是最好还是保持实例字段的私有性。很多惨痛的教训告诉我们,数据的表示形式很可能会改变,但它们的使用方式却不会经变化。当数据保持私有时,表示形式的变化不会对类的使用者产生影响,而且也更容易检测bug。
(2)一定要对数据进行初始化。
Java不会为你初始化局部变量,但是会对对象的实例字段进行初始化。最好不要依赖于系统的默认值,而是应该显式地初始化所有的数据,可以提供默认值,也可以在所有构造器中设置默认值。
(3)不要再类中使用过多的基本类型。
这个想法是要用其他的类替换使用多个相关的基本类型。
(4)不是所有的字段都需要单独的字段访问器和字段更改器。
(5)分解有过多职责的类。
这样说似乎有点含糊,究竟多少算是“过多”?每个人的看法都不同。但是,如果明显地可以将一个复杂的类分解成两个更为简单的类,就应该将其分解。
(6)类名和方法名要能够体现它们的职责。
与变量应该有一个能够反映其含义的名字一样,类也应该如此。
(7)优先使用不可变的类。
LocalDate类以及java.time包中的其他类是不可变的——没有方法能修改对象的状态。类似 plusDays的方法并不是更改对象,而是返回状态已修改的新对象。
更改对象的问题在于,如果多个线程试图同时更新一个对象,就会发生并发更改。其结果是不可预料的。如果类是不可变的,就可以安全地在多个线程间共享其对象。
因此,要尽可能让类是不可变的,