Java之封装
文章目录
- 1.封装
- 1.1 什么是封装
- 1.2 访问限定符
- 1.3 包
- 1.3.1 什么是包
- 1.3.2 导包
- 1.3.3 自定义包
- 2. static
- 2.1 static 修饰成员变量
- 2.2 static 修饰成员方法
- 2.3 static成员变量初始化
- 3. 代码快
- 3.1 普通代码块
- 3.2 实例代码块
- 3.3 静态代码块
- 4. 对象的打印
1.封装
1.1 什么是封装
在Java中,面向对象程序三大特性:封装、继承、多态,而封装就是将对象的状态(数据)和行为(方法)打包在一起,并隐藏对象的内部实现细节,只提供公开的接口(getter和setter方法)来与对象进行交互。
1.2 访问限定符
在Java中,主要通过类和访问权限来实现封装,访问限定符用于控制类、变量、方法或其他引用对象的访问级别。Java支持四种访问限定符
- private:私有访问级别。只对定义它的类可见。
- default:默认访问级别,同一个包中的类可见。当类没有定义访问限定符时,此时默认访问级别为default。
- protected:保护访问级别。对于同一包中的类及其子类是可见的。(介于public和private之间)
- public:公共访问级别。对于同一包中的所有类都是可见的。
一般情况下,我们建议:
- 成员变量定义为private
- 成员方法定义为public
建议不唯一,根据具体场景来使用。
1.3 包
1.3.1 什么是包
包其实就是一个文件夹,为了更好的管理,我们将类划分,把多个类收集成一组,就是一个包。
例如:我们将D盘中的文件划分,将Java语言相关的文件放到Java包中,将C语言相关的文件放到C语言包中,将下载的软件放到app这个包中……
在Java中,包是一种用来组织和管理类和接口的机制。它为开发者提供了一种逻辑分组的方式,使得代码更加模块化、结构化和易于管理。
1.3.2 导包
Java中提供了许多现成的类供我们使用,例如Date类,可以使用 java.util.Date 导入 java.util 这个包中的 Date
类。
例如:
在IDEA中会自动导入包,如果使用其他环境,可以去设置。
当我们需要用到 java.util 中的其他类时,可以使用 java.util.*
1.3.3 自定义包
- 包名和代码路径匹配,例如创建一个 com.bit.demo1 的包,那么它对应的路径就是 com/bit/demo1
- 包名尽量指定成唯一的名字(公司通常会将公司的域名的颠倒的形式来命名包)
- 当我们创建一个Java文件时,最上面的package语句就是,改java文件放到了哪个包中
- 如果一个类没有package语句,该类被放到默认包中。
例如,我们创建一个名为 com.bit.demo1 的包
自定义包的步骤:
-
右键src -> new -> package
-
输入包名
-
此时可以看到我们的磁盘上的目录结构已经被 IDEA 自动创建出来了
-
新建一个java类,我们可以看到顶部出现package语句
-
如果出现 2 步骤所示的图片,可以更改设置
包教会的
2. static
2.1 static 修饰成员变量
static修饰的成员变量,称为静态成员变量。
静态成员变量,不属于某个具体的对象,而是所有对象共享的
静态成员变量的特征:
- 又称为静态属性,不属于某个具体的对象,是类的属性,所有对象共享的。
- 静态成员变量即可以通过类名直接访问,又可以通过对象访问,但是推荐使用类名来访问,因为这样可以更清楚地表明它是属于类而不是某个对象的。
- 存储在方法区。
- 生命周期随着类的加载而创建,随着类的卸载而销毁。
public class Student {
public int id;
public String name;
public int age;
public String sex;
public static String classRoom = "计科一班";
public Student() {
}
public Student(int id, String name, int age, String sex) {
this.id = id;
this.name = name;
this.age = age;
this.sex = sex;
}
}
public class Test1 {
public static void main(String[] args) {
//可以直接通用类名访问
System.out.println(Student.classRoom);
//也可以通过对象访问,但是不建议,这种方法合法不合理
Student student = new Student(1,"zhangsan",12,"男");
System.out.println(student.classRoom);
}
}
在Student类中,成员变量 classRoom 被 static 修饰 ,此时,这个成员变量就不属于这个对象了,所以用类名访问 classRoom
2.2 static 修饰成员方法
在封装中,一般情况下类的成员变量都设置为 private ,而成员方法设置为 public ,当成员变量 classRoom 被设置为 private 后,我们在其他类应该如何访问呢?
在Java中,被 static 修饰的成员方法被称为静态成员方法,是类的方法,而不是某个对象特有的。
静态成员变量一般通过静态成员方法来访问。
public class Student {
private static String classRoom = "计科一班";
public static String getClassRoom(){
return classRoom;
}
}
import com.bit.demo1.Student;
public class StudentTest {
public static void main(String[] args) {
System.out.println(Student.getClassRoom());
}
}
与静态成员变量一样,通过类名调用,不推荐使用对象调用。
注意:
- 静态方法不需要对象调用,所以不能传递 this
- 静态方法中不能调用任何非静态成员变量
public class Student {
private int age;
private static String classRoom = "计科一班";
public static String getClassRoom(){
age = age + 1;
return classRoom;
}
}
public class StudentTest {
public static void main(String[] args) {
System.out.println(Student.getClassRoom());
}
}
运行结果:
- 静态方法中不能调用任何非静态方法(因为非静态方法中有 this 参数)
public class Student {
private int age;
private static String classRoom = "计科一班";
public int getAge(){
return age;
}
public static String getClassRoom(){
age = age + 1;
return classRoom;
}
}
public class StudentTest {
public static void main(String[] args) {
System.out.println(Student.getAge());
}
}
运行结果:
- 可以在非静态成员方法中调用静态方法
2.3 static成员变量初始化
静态成员变量一般不会在构造方法中初始化。
静态成员变量的初始化分为两种,分别为:就地初始化和静态代码块初始化。
- 就地初始化:在定义该静态成员变量时就进行初始化。
- 静态代码块初始化:等下面理解什么是代码块再进行讲解
好多东西啊,真是烦躁,感觉有人在念紧箍咒
3. 代码快
3.1 普通代码块
普通代码块,即定义在方法中的代码块。
public class Test1 {
public static void main(String[] args) {
{
int a = 1;
System.out.println("a = " + a);
}
int b = 2;
System.out.println("b = " + b);
}
}
//运行结果
a = 1
b = 2
这种用法不常见
你小子,肯定又不记了
3.2 实例代码块
实例代码块又叫构造代码快,一般用在初始化实例成员变量。
例如:
public class Student {
private String name;
private int age;
private String sex;
public static String classRoom = "计科一班";
public Student(){
System.out.println("不带参数的构造方法");
}
{
System.out.println("实例代码块");
this.name = "zhangsan";
}
public void show() {
System.out.println("name = " + name + " age = " + age + " sex = " + sex + " claasRoom = " + classRoom);
}
}
public class Test1 {
public static void main(String[] args) {
Student student = new Student();
student.show();
}
}
//运行结果
实例代码块
不带参数的构造方法
name = zhangsan age = 0 sex = null claasRoom = 计科一班
根据执行结果我们可以知道,实例代码块的执行顺序优先于构造方法。
3.3 静态代码块
静态代码快,即被static定义的代码块,一般用于初始化静态成员变量。
例如:我们将上述代码改动一下
public class Student {
private String name;
private int age;
private String sex;
public static String classRoom;
public Student(){
System.out.println("不带参数的构造方法");
}
{
System.out.println("实例代码块");
this.name = "zhangsan";
}
static{
System.out.println("静态代码块");
classRoom = "计科一班";
}
public void show() {
System.out.println("name = " + name + " age = " + age + " sex = " + sex + " claasRoom = " + classRoom);
}
}
public class Test1 {
public static void main(String[] args) {
Student student1 = new Student();
System.out.println("===========");
Student student2 = new Student();
}
}
//执行结果
静态代码块
实例代码块
不带参数的构造方法
===========
实例代码块
不带参数的构造方法
根据执行结果我们得到结论,静态代码块优先被执行,其次是实例代码块,最后是不带参数的构造方法。
上述代码中我们new了两个Student对象,但是执行结果中只出现了一次静态代码快,所以静态代码块只执行一次。
注意:
- 静态代码块只执行一次
- 如果一个类中定义了多个静态代码快,在编译时,编译器会按照定义的先后顺序来执行
- 静态成员变量是类的属性,所以是在JVM加载类的时候开辟空间并初始化的
- 实例代码块只有在创建对象的时候才会执行,构造方法也是。
这个一定要记住
4. 对象的打印
public class Student {
private String name;
private int age;
private String sex;
public static String classRoom;
public Student() {
}
public Student(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
}
public class Test1 {
public static void main(String[] args) {
Student student1 = new Student("zhangsan",12,"男");
System.out.println(student1);
}
}
当我们直接打印对象时,执行结果为
这个结果的结构为:类所在的包名.类名 + @ + 哈希码值
并不是我们想要实现的打印,如果想要实现打印,我们可以直接调用java自带的 toString 方法(快捷键Alt + Insert ,点击toString 即可),也可以重写toString 方法。
public class Student {
private String name;
private int age;
private String sex;
public static String classRoom = "计科一班";
public Student() {
}
public Student(String name, int age, String sex) {
this.name = name;
this.age = age;
this.sex = sex;
}
@Override
public String toString(){
return "[" + name + "," + age + "," + sex + "," + classRoom + "]";
}
}
public class Test1 {
public static void main(String[] args) {
Student student1 = new Student("zhangsan",12,"男");
System.out.println(student1);
}
}
//执行结果
[zhangsan,12,男,计科一班]
如果想要了解这个部分的详细内容,我发现了一个博主的博客link
,我认为讲的很详细,点击进去就可以了
觉得我写的博客对你有用,给我点个赞,嘻嘻