文章目录
javalearn-1
Java核心技术.卷I(第11版)
第4章:对象与类
1.基础概念
面向对象程序设计(object-oriented programming, OOP)
实例(instance):由类构建的对象的过程叫创建类的实例
封装(encapsulation):关键就是只能通过对象的方法去访问对象数据
实例字段(instance field):对象中的数据
2.类之间的关系
-
依赖(“uses-a”)
一个类的方法使用或操纵另一个类的对象
但我们要尽可能减少类的耦合
-
聚合(关联)(“has-a”)
一个类的对象包含了另一个类的对象作为数据
-
继承(“is-a”)
一个类继承自另一个类
UML表达:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-xbZgQi3O-1661949990466)(images/image-20220819103022066.png)]
3.类
Java对象在堆中构造,使用new
。
如果可以从变量的初始值推导出他们的类型,可以使用关键字var
,无需指定特定类型。多用于局部变量。
一个源文件可以包含多个类,但只有一个公共类(使用public
修饰),且源文件名和公共类同名。编译的时候,会按照类的个数生成等数目的类文件(xxx.class
)。最后会将办好main
方法的类名提供给字节码解释器,以启动该程序。
UNIX的make工具也是起编译作用。
构造器:
- 与类名同名
- 每个类可以有多个构造器
- 构造器参数不定
- 构造器无返回值
- 构造器是与
new
操作符连用,创建实例
封装优点:
get
方法,又称字段访问器
set
方法,又称字段更改器
- 保证字段不被外界破坏,出现异常只要调试对应方法就可以
- 可以改变内部实现,且不影响其他代码
final实例字段:
使用final
修饰符声明字段时,必须在创建对象的时候设置值,并且这个值不会再改变。
也就是常量。
4.静态字段、静态方法
字段或者方法被static
关键字修饰
表示它属于类,即使不是实例化,他也存在,且只有一个,被大家共享使用。即可以跳过创建对象而被直接调用。
static final
静态常量
用于工厂方法(factory method),大致就是调用静态方法来创建不同的对象
初始代码块也可以使用static
修饰,这样初始代码块在类第一次加载的时候,会运行,对静态字段按运行做初始化。(用于静态字段较复杂的初始化)
5.方法参数
- 按值调用(java):传递参数值
- 按引用调用:传递参数地址
java都是按值调用。虽然可以传对象引用,但对象引用也是按值传递的!
方法得到的是所有参数值得一个副本。方法不能修改参数变量得内容。
也就是,参与方法计算得的都是参数的副本。
但是,传递对象引用时,传递的是对象引用的副本,但是指向的都是同一个对象,因此对象的内容是可以发生变化的!
具体例子就是:交换方法对两个对象不会起到交换作用;交换的只是对象引用的副本,在方法结束后就被丢弃了。
6.对象构造
构造器,没有其他构造器时,默认是无参构造器,但是自定义了其他构造器时,必须提供无参构造器。
重载(overloading):方法名相同,参数不同。编译器会根据参数类型进行匹配,否则编译错误。
方法,需要指定方法名和参数类型,与返回类型无关。
签名(signature)= 方法名 + 参数类型
默认值,数值0,布尔值false,对象引用null
this:
- 指示一个方法的隐式参数,指所构造的对象
- 用于构造器第一句,
this(...)
,表示调用同一类的另一个构造器,类似调用公共构造器来合并。
初始化块(initiaization block):构造对象时就会被执行,一个类可以包含多个代码块。
首先运行代码块,再运行构造器主体部分
不常见,一般这种的就写在构造器里了
public class Clazz{
// 声明字段
private int a = 1;
...;
// object initialization block 1
{
...;
}
// func
}
7.初始化字段的方法
- 在构造器中设置值
- 在声明中设置值
- 初始化块(initiaization block):一般就合并在构造器了,不常用‘
8.包
主要原因:确保类名的唯一性,不同包相同类名的类不会冲突。
导入:
import java.time.*;
import java.time.LocalDate;
编译器会定位包中的类。
静态导入,import static xxx
,允许导入静态方法和静态字段,阅读困难,没人用。
package xxx:在包中增加类,一般IDE会自动做这件事。包名和目录路径是一一对应的。
9.文档注释
-
类注释
放在
import
语句之后,类定义之前import xxx; /** * * */ public class Clazz{ ...; }
也可以使用
/*内容*/
,不推荐,不规范 -
方法注释
@param
,@return
,@throws
等/** * func description * @param a description * @param b description * @return description */ public int add(int a, int b){ ... }
-
字段注释
一般对静态常量建立文档注释
/** * description */ public static final double PI = 3.14;
-
通用注释
一些文档描述
@author name
@version text
@see
,@link
,超链接@reference
, see also部分增加一个超链接,做引用
-
包注释
在包目录中添加一个单独的文件
- 名为
package-info.java
的java文件,只包含/** */
的注释和package
语句 - 名为
package.html
的HTML文件。会抽取<body>...</body>
之间的所有文本作为注释。
- 名为
-
注释抽取
就是把所有的html注释文件都抽取到同一个目录之下。
10. 类设计技巧
目标:符合OOP
技巧:
-
保证数据私有
采用访问器方法和更改器方法对数据执行操作。后续做修改也很方便,因为都是get和set,不用逐个检查在哪里用了变量,更容易检测bug。
-
对数据进行显示的初始化
显示初始化,对变量提供默认值,不依赖系统的默认值,有隐患。
-
不要过多使用基本类型
大意是,能转换成对象的,应用对象代替,这样使类更易于理解。
-
考虑字段是否需要
get
和set
方法比如静态常量,一些不需要更改的字段,不希望别人获取和修改的字段
-
分解过多职责的类
就是解耦,不要杂糅,使逻辑更清晰,对象更明确
-
类名、方法名要具有实际含义
见名知义
-
优先使用不可变的类
不可变:没有方法能修改对象的状态,或者返回状态已经修改的新对象
一个好处是,在多线程中共享是安全的。