封装,是面向对象的三大特性之一。
封装一词,可以有多种理解:
- 把多行代码打包为一个方法
- 隐藏内部的细节,只暴露统一的接口
在java中的面向对象,封装也有多种意义
- 把每一个java文件使用package打包
- 把具有相同属性、行为的对象归为一类
- 类成员拥有4种权限修饰符
- 把一个类的属性私有化,并使用getter/setter方法访问
package与import
包,是java工程的重要结构,一个工程可以有多个包,每个包对应的是一个文件夹
包(package)用于管理java文件,同一个包下的外部类不可以同名,在不同包下的类可以同名,,在一个文件夹下,可以有多个 .java 文件,每个java文件可以有多个类,有且仅有一个类为public,其他外部类只能是default
每个java文件头部第一行使用package语句打包,语法为 package 文件夹名
package abc.def; // 在src下的abc目录下的def目录
如果不打包,则在默认包下,但它将无法被其他类导入使用,使用import 语句在其他任一 java文件中使用import 包名.类名
import abc.def.MyClass; // abc.def包下的 MyClass 类
通常认为java工程中src目录下是java文件,该目录即default目录
导包时,还需要注意:
- java文件中default修饰的外部类不可以导入
- 可以使用 包名.* 导入该包下所有的类
- 同一个包下不需要使用import语句导包
类与对象
什么是类?什么是对象?
类:表示一类具有相同属性、行为的对象的集合,是一个抽象概念
对象:对象是指根据类创建的一个实例化的实体
类与对象的关系
类,表示一个模板,在编写对象前,必须先有类这个模板
对象,对象是类的实例,对象是由类这个模板创建(new)的
java类体结构
类体中可以有如下6种内容
- 成员变量(包含静态)
- 成员方法
- 构造方法
- 静态代码块
- 非静态代码块(实例代码块)
- 内部类
其中,用的最多的是,”成员变量” 和 “成员方法”
例如,创建一个 Student 类,即编写 class 代码
- 属性(成员变量):姓名,年龄
- 方法(成员方法):吃饭,学习,睡觉
public class Student{
String name; //姓名
int age; //年龄
public void eat(){
System.out.println("开始吃饭");
}
public void sleep(){
System.out.println("开始睡觉");
}
public void study(){
System.out.println("开始学习");
}
}
new关键字,创建对象
new 关键字用于 从类中创建对象,使用new后,每个对象都将获得各自的内存
语法:
类名称 对象名称 = new 类名称(参数);
对象名称,是一个变量,遵守标识符的命名规则
其中的参数,是构造函数中传递的参数,构造函数可以为空参;
下面,创建一个 Student 对象,并使用(获取属性和调用方法)
public static void main(String[] args) {
Student stu = new Student();
System.out.println("学生的名称是"+stu.age);
stu.study();
}
javaBean
一个标准的java类,叫做javaBean,拥有4个特点
- 所有的成员变量,都要使用 private 修饰
- 每个成员变量,都必须有一对 Getter/Setter
- 必须有一个无参构造
- 必须有一个全参构造
4种权限修饰符
4种权限修饰符,是针对类中成员的,包括成员属性(包括静态)、成员方法、局部类等
这里的default并不是switch/case的default,而是表示“缺省”,4种权限修饰符访问控制如下:
修饰符 | 当前类 | 同一包内 | 不同包子类 | 不同包非子类 |
---|---|---|---|---|
public | Y | Y | Y | Y |
protected | Y | Y | Y | N |
default | Y | Y | N | N |
private | Y | N | N | N |
getter/setter方法
这2种方法,是把属性私有化,然后用public方法公开访问的手段,那么,它是否有意义?它到底有什么意义?
这2个方法是有意义的,并非多此一举,例如:
- 使用getter/setter暴露接口时,即使修改了内部属性,但外部并不影响
- 可以对数据进行额外的校验,比如存值限定范围
- 多态时调用子类属性
- 可以用于lambda表达式
- 可以用于惰性求值,当数据被调用,再计算属性
- 在多线程时,线程安全
- …
在编写getter/setter时,通常使用getXxx()取值,然后使用setXxx(x)存值
但对于boolean类型,取值是isXxx(),例如以下实例
public class Human {
private String name;
private int age;
private char sex;
private boolean check;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public boolean isCheck() { // 不是setCheck
return check;
}
public void setCheck(boolean check) {
this.check = check;
}
}