文章目录
面向对象程序设计概述
面向对象的程序是由对象组成,每个对象都包含对用户公开的特定功能部分和隐藏的实现部分。
类
类是构造对象的模板。
由类构造对象的过程称为实例化。
封装
封装是处理对象的重要概念。一句话说,封装就是将数据和行为组合在一个保重,并对使用者隐藏具体的实现方式。其中,数据称为实例字段,行为称为方法。
实现封装的关键在于:绝不能让类中的方法直接访问其他类的实例字段。程序只能通过对象的方法与对象数据进行交互(setter/getter方法)。
继承
面向对象编程有一个特别的优势:就是可以通过扩展一个类来构建新类。
在扩展一个已有的类后,新类拥有已有类的全部属性和方法,所以新类只需要提供新的属性和方法即可。
对象
一个对象,有三种特性:
- 对象的行为:对象能使用什么方法
- 对象的状态:调用方法后由什么响应
- 对象的标识:如何区分不同的对象
对象的状态是不会自己改变,而是通过对象的行为而改变。
每个对象都有一个唯一的标识。
类之间的关系
类与类之间最常见的关系有三种:
-
依赖(uses-a)
一个类的方法使用或者操纵另一个类的对象。
这种关系最为常见,但是会带来系统的强耦合,需要尽量避免。
Java中,依赖关系一般表现为局部变量,方法的形参或者对形态方法的调用。
-
聚合(has-a)
一个类的对象包含另一个类的对象。
Java中,聚合关系一般体现为局部变量。
-
继承(is-a)
使用类
对象与对象变量
要想使用类,必须构造该类的对象,并指定其初始状态。然后对对象应用方法。
Java中,使用构造器来构造并初始化对象。
构造器有如下特点:
- 构造器与类同名
- 每个类都可以由一个或以上的构造器
- 构造器可以无参,也可以有参
- 构造器没有返回值
- 构造器总是和new操作符一起使用
隐式参数和显示参数
使用对象调用方法时,方法都会由两个参数。
TestClass tc = new TestClass();
tc.setId(1);
上面代码中我们可以看到,调用对象tc的setId方法, 传入了一个参数“1”这个参数就是显示参数。
⭐️隐式参数,就是指出现在方法名前的对象。在方法中,可以使用this关键字指示隐式参数。
再说封装
前面讲过,封装就是对使用者隐藏具体的实现方式。下面是一个最简单的封装类。
public class TestClass {
private Integer id;
private String name;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
这个类中,有三个部分:
- 私有化的字段
- 公共的getter方法(访问器)
- 公共的setter方法(修改器)
这种封装带来了两个好处,
- 改变方法的内部实现,不会影响其他代码
- 更改其方法可以完成错误检查。
基于类的访问权限
Java中,访问权限有四种:
访问权限 | 本类中使用 | 本包中使用 | 子类可使用 | 整个项目中均可使用 |
---|---|---|---|---|
private | √ | × | × | × |
default | √ | √ | × | × |
protected | √ | √ | √ | × |
public | √ | √ | √ | √ |
final字段
将实例字段定义为final,这样的字段必须在构造对象时实例化,并且以后无法修改这个值。
public class FinalTest {
private Integer id;
private final String name;
public FinalTest(String name) {
this.name = name;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
}
在FinalTest这个类中,我们为name实例增加了final关键字,此时编译器会告诉我们将件事情:
- 因为name属性必须初始化,所以必须提供一个带name属性的构造器
- name属性无法修改,所以无法提供setter方法。
若将final关键字修饰用来修饰一个类,final关键字只表示对象引用不会再指向另一个不同的对象。但是该对象的状态是可以改变的。
静态字段与静态方法
静态字段和静态方法都使用static关键字进行修饰
静态字段
当一个字段被static关键字修饰时,表示这个类只有这一个这样字段。换句话说,这个字段属于这个类,而不属于任何对象。
而对于非static字段,每个对象都有自己的一个副本。
public class StaticDemo1 {
private static Integer id = 1;
private String name;
}
对于静态字段,通常再声明时就进行赋值。
静态常量
静态常量就是使用final static修饰的变量。
由于每个类对象都可以修改公共字段,所以最好不要有公共字段。静态常量却不会有这个问题。
java.lang.Math类中定义了很多静态常量,比如:
public final class Math {
public static final double E = 2.7182818284590452354;
}
由于E被赋值为final,无法对值进行修改,所以可以使用public修饰。
静态方法
静态方法是不在对象上执行的方法。
静态方法不再属于对象,而是属于这个类。
java.lang.Math类中定义了很多静态方法,比如:
public static double sin(double a) {
return StrictMath.sin(a);
}
若要调用静态方法,无需创建对象。使用类直接调用即可。
⭐️注意:非静态方法中可以调用静态方法;而静态方法中只能调用静态方法,无法调用非静态方法。
方法参数
方法传参一共有两种方式:
- 按值调用:方法接收的是调用者提供的值。
- 按引用调用:方法接收的是调用者提供的变量地址。
方法可以修改按引用调用的参数的值,而不能修改按引用调用的参数的值。
⭐️Java语言属于按值调用,也就是说,Java中,方法得到的是所有参数值的一个副本,并且不能修改参数的值。
- 如果参数为基本数据类型,那么方法无法。
- 如果参数为引用数据类型:
- 方法可以修改参数的状态
- 方法无法让一个对象参数引用一个新的对象
对象构造
重载
一个类中如果多个方法有相同的名字、不同的参数,就出现了重载。
一个类中,可以有多个构造器,这些构造器就是方法的重载:
package priv.ihch17.clazz;
public class TestClass {
private Integer id;
private String name;
// 无参构造器
public TestClass() {
}
// 有参构造器
public TestClass(Integer id, String name) {
this.id = id;
this.name = name;
}
}
默认字段初始化
如果构造器中没有显式的为字段设置初始值,那么就会被自动的赋予默认值:数值为0、布尔值为false、对象引用为null。
无参构造器
如果一个类没有编写构造器,那么编译器就会提供一个无参构造器。
如果编写了构造器,那么编译器就不再会提供无参构造器。
包
略
JAR文件
略
文档注释
通过javadoc,可以有源文件生成一个HTML文档。
可以由javadoc识别的注释,成为文档注释,文档注释由/**开头。
注释的插入
javadoc可以从如下位置抽取信息:
- 模块
- 包
- 公共类与接口
- 公共的和受保护的字段
- 公共的和受保护的构造器和方法
文档注释类型
-
类注释:类注释必须放在import之后、类定义之前。
- @author 作者:作者信息
- @version num:版本号为num
-
方法注释:方法注释必须放在所描述的方法之前。
在方法注释中,可以使用如下标识:
- @param variable description:为参数添加注释。每个参数都有一个独自的注释。可以为多行,可以有HTML标签。
- @return description:为返回值添加注释。可以为多行,可以有HTML标签。
- @throws class description:为异常添加注释。每个异常都有一个独立的注释
// 这是类注释
/**
* 类描述
* @author 作者
* @version 1.0
*/
public class JavadocDemo {
// 这是方法注释
/**
* 方法描述
* @param a 参数1描述
* @param b 参数2描述
* @return 返回值描述
*/
public Integer method1(Integer a,Integer b){
return a+b;
}
}
文档抽取
文档注释完成后,可以使用javadoc命令抽取注释,并成为一个HTML文档。
步骤如下:
-
切换到源文件的目录
-
进行提取,提取有三种方式:
-
如果就为一个包的源文件提取文档:
javadoc -d docDirectory 包名
-
如果为多个包中的源文件提取文档:
javadoc -d docDirectory 包名1 包名2... // 多个包名之间使用空格分隔
-
如果只为一个无包文件提取文档:
javadoc -d docDirectory *.java
-
如果省略了-d docDirectory参数,则HTML文档会生成再当前目录下。
类设计技巧
- 一定要保证数据私有
- 一定要对数据进行初始化。
- 不要再类中使用过多的基本类型
- 不是所有的字段都需要setter/getter方法
- 类的职责不能过多
- 类名和方法名要见名知义。
- 优先使用不可变类。