当前位置: 首页 > 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.xdnf.cn/news/1112365.html

相关文章:

  • 车载操作系统 --- Linux实时化与硬实时RTOS综述
  • 数据结构——散列表
  • 【PTA数据结构 | C语言版】用两个栈实现队列
  • 【GESP】C++ 2025年6月一级考试-客观题真题解析
  • MoE(混合专家模型):大模型时代的“模块化超级大脑”——从原理到实战的深度革命
  • 初识JDBC
  • GPU编程入门:CUDA与OpenCL全面解析
  • C语言基础知识--动态内存管理
  • 【时间之外】AI在农机配件设计场景的应用
  • bp使用爆破模块破解pikachu的登陆密码
  • java堆的创建与基础代码解析(图文)
  • BKD 树(Block KD-Tree)Lucene
  • TCP与UDP协议详解:网络世界的可靠信使与高速快递
  • UnityShader——SSAO
  • 微信小程序121~130
  • 时序分解 | Matlab基于GWO-FMD基于灰狼算法优化特征模态分解-2025-7-12
  • 直播录屏技术揭秘:以抖音直播录屏为例
  • LLM 不知道答案,但是知道去调用工具获取答案?
  • 基于STM32F412+RT-Thread的智能汽车CAN通信仪表盘
  • ADSP-1802这颗ADI的最新DSP应该怎么做开发(一)
  • JavaScript 常见10种设计模式
  • TCP详解——各标志位
  • linux 系统找出磁盘IO占用元凶 —— 筑梦之路
  • Java从入门到精通!第四天(面向对象(一))
  • HTTP和HTTPS部分知识点
  • python库之jieba 库
  • 模拟注意力:少量参数放大 Attention 表征能力
  • C#与FX5U进行Socket通信
  • 【设计模式】桥接模式(柄体模式,接口模式)
  • OneCode 3.0架构深度剖析:工程化模块管理与自治UI系统的设计与实现