当前位置: 首页 > news >正文

零基础 “入坑” Java--- 九、类和对象(二)

文章目录

  • 一、封装
    • 1.何为封装
    • 2.初识封装
    • 3.封装之包
      • 3.1 导入包中的类
      • 3.2 再谈访问修饰限定符
  • 二、深入static
  • 三、代码块
    • 1.普通代码块
    • 2.构造代码块
    • 3.静态代码块
  • 四、对象的打印

面向对象有三大基本思想:封装、继承、多态。 在类和对象阶段,我们先来了解一下封装。

一、封装

1.何为封装

封装即:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口用来和对象进行交互。

对于这段晦涩难懂的解释,我们举个例子来说明一下:在我们使用电脑主机时,我们只需插入U盘即可读取U盘内容,但是在主机内部,却需要经过一系列很复杂的操作。我们可以将封装简单理解为:套壳屏蔽细节。

2.初识封装

我们先来定义一个学生类:

class Student {public String name; //姓名public int age; //年龄public void show() {System.out.println("姓名:" + this.name + " 年龄:" + this.age);}
}
public class Test {public static void main(String[] args) {Student student = new Student();student.name = "小王";student.age = 20;student.show();}
}

此时这个类中有两个被 public 修饰的成员变量,一个成员方法,代码可以正常运行。

但是当我们将成员变量的修饰符换为 private 时,main方法中的name和age就都变红了(如下图),此时再次运行,程序就会报错。这是因为:被private修饰之后,代表此变量只能在当前类中使用。
在这里插入图片描述

此时,name和age就相当于已经被我们封装上了,当我们想在类外使用name和age时,就需要使用Getter和Setter:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
我们在空行单击鼠标右键,选择生成,再选择Getter和Setter,根据需要选择并生成方法,当我们在类外需要使用被封装的变量时,就可以调用生成的方法:

class Student {private String name; //姓名private int age; //年龄public void show() {System.out.println("姓名:" + this.name + " 年龄:" + this.age);}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 class Test {public static void main(String[] args) {Student student = new Student();//调用生成的方法student.setName("小王");student.setAge(20);student.show();}
}

在类中,一般情况下我们将成员变量设置为private,成员方法设置为public。


在这里插入图片描述
对于访问修饰限定符一共有四种:public我们可以广泛使用,private我们只能在当前类中使用;而对于剩下的两个,我们先来了解一下包是什么。

3.封装之包

在Java中,包是对类、接口等封装机制的体现,是一种对类或者接口等很好的组织方式。 包还有一个作用:在同一个工程中允许存在相同名称的类,只要在不同的包中即可。
在这里插入图片描述
在这里插入图片描述

3.1 导入包中的类

Java中提供了很多现成的类供我们使用,如:

import java.util.Arrays;
import java.util.Scanner;
public class Test {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);int[] array = {1,2,3,4,5};System.out.println(Arrays.toString(array));}
}

在这里插入图片描述
但并不建议采用简写的方式,可能会导致冲突情况的产生。


import java.util.*;
import java.sql.*;
public class Test {public static void main(String[] args) {Date date = new Date();}
}

这段代码不能正常运行,是因为util和sql中都存在Date类,这会导致歧义,编译出错。这种情况下,就需要使用完整的类名:

import java.util.*;
import java.sql.*;
public class Test {public static void main(String[] args) {//完整书写格式:java.util.Date date = new java.util.Date();}
}

此时代码可以正常运行。


我们还可以使用 import static 导入包中的静态方法和变量,对于这一点了解即可,使用很少。

3.2 再谈访问修饰限定符

在这里插入图片描述
学习完包,我们再来理解这个图片:default即默认权限,当不写访问修饰限定符时,都是默认为default。default因为其访问范围特点,也叫包访问权限。(何为protected我们以后再介绍。)

封装小结:
1.何为封装:对类中的成员通过private关键字进行隐藏,只对类外提供公开的接口(如Getter和Setter)。
2.封装的意义:隐藏类的实现细节,提高安全性。

二、深入static

class Student {private String name; //姓名private int age; //年龄public Student(String name, int age) {this.name = name;this.age = age;}public int classroom; //班级
}
public class Test {public static void main(String[] args) {Student s1 = new Student("小王", 18);s1.classroom = 310;Student s2 = new Student("小李", 17);s2.classroom = 310;Student s3 = new Student("小刘", 19);s3.classroom = 310;}
}

我们依旧使用学生类举例:先定义一个学生类,再实例化三个对象,依次为这三名学生的班级进行赋值,将他们分配到一个班级:
在这里插入图片描述
既然三名学生在一个班级,那么我们对代码进行修改:

class Student {private String name; //姓名private int age; //年龄public Student(String name, int age) {this.name = name;this.age = age;}public static int classroom; //班级
}
public class Test {public static void main(String[] args) {Student s1 = new Student("小王", 18);Student s2 = new Student("小李", 17);Student s3 = new Student("小刘", 19);Student.classroom = 310;}
}

在这里插入图片描述
在Java中,被static修饰的成员,称为静态成员或者类成员,其不属于某个具体的对象,是所有对象所共有的。 既可以通过对象访问,也可以通过类名访问,但推荐使用类名访问。

静态成员变量存储在方法区中,其生命周期伴随类(随类的加载而创建,随类的结束而销毁)


静态成员不能直接调用非静态成员,所以在静态方法中不能使用this,但是可以通过对象的引用间接调用:

class Student {private String name; //姓名public void show() {System.out.println("嘻嘻");}public static void test() {System.out.println("哈哈");//通过对象的引用调用 √Student student = new Student();student.name = "小王";student.show();//直接调用 ×//name = "小王";//show();}
}

在学习构造方法时我们知道:构造方法的作用就是对 对象中的成员变量进行初始化;但是,静态成员变量一般不会放在构造方法中进行初始化。

静态成员变量的初始化有两种方式:就地初始化 和 静态代码块初始化。

就地初始化即:在定义时直接设定初始值:

class Student {public static int classroom = 310; //班级
}

静态代码块初始化:什么是代码块呢???

三、代码块

使用"{}"定义的一段代码称为代码块。 代码块又可分为:普通代码块、构造代码块、静态代码块、同步代码块(先不学)。

1.普通代码块

普通代码块即:定义在方法中的代码块:

    public static void main(String[] args) {//普通代码块{int x = 10;System.out.println(x);}//代码块内的变量不能在代码块外使用System.out.println(x);}

2.构造代码块

构造代码块即:定义在类中的代码块(无访问修饰限定符)。也叫:实例代码块。构造代码块常用于初始化实例成员变量(非静态成员变量)。

class Student {public String name;public int age;//构造代码块{this.name = "小王";this.age = 20;System.out.println("构造代码块");}//无参构造方法public Student() {System.out.println("无参构造方法");}public void show() {System.out.println("姓名:" + this.name + " 年龄:" + this.age);}
}
public class Test_dmk {public static void main(String[] args) {Student student = new Student();student.show();}
}

运行结果为:
在这里插入图片描述
由此可得出:构造代码块先于构造方法执行。

3.静态代码块

使用static定义的代码块称为静态代码块,常用于初始化静态成员变量:

class Student {public String name;public int age;public static int classroom;//构造代码块{this.name = "小王";this.age = 20;System.out.println("构造代码块");}//静态代码块static {classroom = 310;System.out.println("静态代码块");}//无参构造方法public Student() {System.out.println("无参构造方法");}public void show() {System.out.println("姓名:" + this.name + " 年龄:" + this.age);}
}
public class Test_dmk {public static void main(String[] args) {Student student = new Student();student.show();}
}

运行结果为:
在这里插入图片描述
由此可得出:静态代码块先于构造代码块,先于构造方法执行。

但是当我们实例化两个对象时,会发现"静态代码块"只输出了一次。

我们总结一下:

1.无论实例化多少对象,静态代码块都只会执行一次。
2.静态成员变量是类的属性,在类加载时就会为其开辟空间并初始化(静态代码块在类加载时就会执行)。
3.当一个类中有多个静态代码块,编译器会根据静态代码块的顺序依次执行。
4.构造代码块只有在实例化对象时才会执行(通过new关键字实例化对象)。

四、对象的打印

在静态代码块的例子中,我们使用自己写的show方法打印成员变量。在Java中,有一个便捷的方法可以帮助我们完成这个任务,就是重写toString方法:
在这里插入图片描述
在这里插入图片描述
我们在空行单击鼠标右键,选择生成,再选择toString,选择需要显示的成员变量,就会生成如下图的方法:
在这里插入图片描述
当我们没有重写toString方法时,因为student是引用类型,所以存储的值为地址:

        Student student = new Student();System.out.println(student);

但当我们重写toString方法后,再次运行这段代码,打印的结果就是toString方法中返回值的形式。


Ending。

http://www.dtcms.com/a/275611.html

相关文章:

  • 【YOLOv8-obb部署至RK3588】模型训练→转换RKNN→开发板部署
  • 详解梯度消失和梯度爆炸(反向传播)?
  • 2025年亚太杯(中文赛项)数学建模B题【疾病的预测与大数据分析】原创论文讲解(含完整python代码)
  • 【Java入门到精通】(三)Java基础语法(下)
  • # win11 连接共享打印机报错:0x00000040 或者 0x00000709或者 x0000011b 的解决方法
  • ubuntu系统宝塔进程守护管理器开机启动失败问题
  • 设计模式:单一职责原则
  • 注解驱动的知识中枢:MCPServer赋能AI业务的技术架构与实践
  • Mastercam 2026中文版网盘资源下载与安装教程共享
  • JAVA--双亲委派机制
  • 历史数据分析——云南白药
  • Matplotlib 全面使用指南 -- 紧密布局指南 Tight layout guide
  • Leetcode力扣解题记录--第3题(滑动窗口)
  • Python 实战:构建 Git 自动化助手
  • pgsql模板是什么?
  • 深入理解设计模式:建造者模式详解
  • AI产品经理面试宝典第12天:AI产品经理的思维与转型路径面试题与答法
  • 分音塔科技(BABEL Technology) 的公司背景、股权构成、产品类型及技术能力的全方位解读
  • LRU缓存机制完全实战:链表的工程落地与面试通关
  • 杭州乐湾科技有限公司的背景、产品体系与技术能力的全方位深度分析
  • [论文阅读] 人工智能 + 软件工程 | AI助力软件可解释性:从用户评论到自动生成需求与解释
  • 仅27M参数!SamOutVX轻量级语言模型刷新认知,小身材也有大智慧
  • 后端定时过期方案选型
  • 构建AI Agent的完整实战指南:从邮件助手案例看6步落地方法
  • SpringBoot整合Swagger2快速指南
  • Elasticsearch 线程池
  • nginx反向代理实现跨域请求
  • 从零到一:企业如何组建安全团队
  • Go语言高并发聊天室(二):WebSocket服务器实现
  • 白皮精读——2025医疗数据合规白皮书 【附全文阅读】