javaSE類和對(duì)象進(jìn)階用法舉例詳解
前言
在掌握了類和對(duì)象的基礎(chǔ)概念后,我們需要進(jìn)一步學(xué)習(xí)面向?qū)ο蟮暮诵奶匦约斑M(jìn)階用法。本文將深入探討封裝的實(shí)現(xiàn)、static 成員的特性、代碼塊的作用以及對(duì)象打印的技巧,幫助你構(gòu)建更完善的面向?qū)ο缶幊讨R(shí)體系。
一、封裝
封裝是面向?qū)ο蟮娜蠛诵奶匦裕ǚ庋b、繼承、多態(tài))之一,其核心思想是將類的屬性和實(shí)現(xiàn)細(xì)節(jié)隱藏起來,只對(duì)外暴露必要的接口供其他對(duì)象訪問。通過封裝,可以提高代碼的安全性、可維護(hù)性和復(fù)用性。
1.訪問限定符
Java中主要通過類和訪問權(quán)限來實(shí)現(xiàn)封裝:類可以將數(shù)據(jù)以及封裝數(shù)據(jù)的方法結(jié)合在一起,更符合人類對(duì)事物的認(rèn)知,而訪問權(quán)限用來控制方法或者字段能否直接在類外使用。Java中提供了四種訪問限定符:

在涉及包之前,先用private和publlic來幫助大家理解一下訪問限定符的使用。
例:
class Student{
private String name;
private int age;
private double score;
public Student(String name, int age, double score) {
this.name = name;
this.age = age;
this.score = score;
}
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 double getScore() {
return score;
}
public void setScore(double score) {
this.score = score;
}
}
public class Test2 {
public static void main(String[] args) {
Student student = new Student("xiaoming",9,78);
System.out.println(student.name);/*報(bào)錯(cuò),在Test2類中
調(diào)用Student類中的成員變量name,但是name
被private限定符修飾,所以沒法直接使用*/
student.setName("zhangsan");
System.out.println(student.getName());
/*不會(huì)報(bào)錯(cuò):getName和setName都用public作為限定符來修飾,
在不同包不同類中也可以隨意調(diào)用*/
}
}
然而,如果想借助getName和setName來改變name的值過于麻煩還需要再寫兩個(gè)成員方法,所以java提供了一種一鍵生成方法的簡便方法:




只需要按照?qǐng)D中所示方法可以直接生成方法。
我使用的是漢化版的idea,沒有漢化版的應(yīng)該如下圖所示:

2.包
2.1包的概念
在面向?qū)ο篌w系中,提出了一個(gè)軟件包的概念,即:為了更好的管理類,把多個(gè)類收集在一起成為一組,稱為軟件包。有點(diǎn)類似于目錄。比如:為了更好的管理電腦中的歌曲,一種好的方式就是將相同屬性的歌曲放在相同文件下,也可以對(duì)某個(gè)文件夾下的音樂進(jìn)行更詳細(xì)的分類。

2.2導(dǎo)入包
Java 中已經(jīng)提供了很多現(xiàn)成的類供我們使用. 例如Date類:可以使用 java.util.Date 導(dǎo)入 java.util 這個(gè)包中的 Date類.
public class Test {
public static void main(String[] args) {
java.util.Date date = new java.util.Date();
// 得到一個(gè)毫秒級(jí)別的時(shí)間戳
System.out.println(date.getTime());
}
}
但是這種寫法比較麻煩一些, 可以使用 import語句導(dǎo)入包.
import java.util.Date;
public class Test {
public static void main(String[] args) {
Date date = new Date();
// 得到一個(gè)毫秒級(jí)別的時(shí)間戳
System.out.println(date.getTime());
}
}
如果需要使用 java.util 中的其他類, 可以使用 import java.util.*;
import java.util.*;
public class Test {
public static void main(String[] args) {
Date date = new Date();
// 得到一個(gè)毫秒級(jí)別的時(shí)間戳
System.out.println(date.getTime());
}
}
可以使用import static導(dǎo)入包中靜態(tài)的方法和字段。
import static java.lang.Math.*;
public class Test {
public static void main(String[] args) {
double x = 30;
double y = 40;
// 靜態(tài)導(dǎo)入的方式寫起來更方便一些.
// double result = Math.sqrt(Math.pow(x, 2) + Math.pow(y, 2));
double result = sqrt(pow(x, 2) + pow(y, 2));
System.out.println(result);
}
}
2.3自定義包
基本規(guī)則
1.在文件的最上方加上一個(gè) package 語句指定該代碼在哪個(gè)包中.
2.包名需要盡量指定成唯一的名字, 通常會(huì)用公司的域名的顛倒形式(例如 com.bit.demo1 ).
3.包名要和代碼路徑相匹配. 例如創(chuàng)建 com.bit.demo1 的包, 那么會(huì)存在一個(gè)對(duì)應(yīng)的路徑 com/bit/demo1 來存儲(chǔ)代碼.
4.如果一個(gè)類沒有 package 語句, 則該類被放到一個(gè)默認(rèn)包中
操作步驟
在 IDEA 中先新建一個(gè)包: 右鍵 src -> 新建 -> 包

在彈出的對(duì)話框中輸入包名, 例如 com.bit.demo1

在包中創(chuàng)建類, 右鍵包名 -> 新建 -> 類, 然后輸入類名即可.

在新創(chuàng)建的 Test.java 文件的最上方, 就出現(xiàn)了一個(gè) package 語句

2.4常見的包
- java.lang:系統(tǒng)常用基礎(chǔ)類(String、Object),此包從JDK1.1后自動(dòng)導(dǎo)入。
- java.lang.re?ect:java 反射編程包;
- java.net:進(jìn)行網(wǎng)絡(luò)編程開發(fā)包。
- java.sql:進(jìn)行數(shù)據(jù)庫開發(fā)的支持包。
- java.util:是java提供的工具程序包。(集合類等) 非常重要
- java.io:I/O編程開發(fā)包。
二、static成員
在Java中,被static修飾的成員,稱之為靜態(tài)成員,也可以稱為類成員,其不屬于某個(gè)具體的對(duì)象,是所有對(duì)象所共享的。
1.static修飾成員變量
static修飾的成員變量,稱為靜態(tài)成員變量,靜態(tài)成員變量最大的特性:不屬于某個(gè)具體的對(duì)象,是所有對(duì)象所共享的。
【靜態(tài)成員變量特性】
- 不屬于某個(gè)具體的對(duì)象,是類的屬性,所有對(duì)象共享的,不存儲(chǔ)在某個(gè)對(duì)象的空間中
- 既可以通過對(duì)象訪問,也可以通過類名訪問,但一般更推薦使用類名訪問
- 類變量存儲(chǔ)在方法區(qū)當(dāng)中
- 生命周期伴隨類的一生(即:隨類的加載而創(chuàng)建,隨類的卸載而銷毀)
class Student{
public String name;
public String gender;
public int age;
public double score;
public static int classroom = 1;
}
public class One {
public static void main(String[] args) {
Student student1 = new Student();
Student student2 = new Student();
Student student3 = new Student();
System.out.println(Student.classroom);
System.out.println(student1.classroom);
System.out.println(student2.classroom);
System.out.println(student3.classroom);
}
}
靜態(tài)成員變量可以直接通過類名訪問也可以通過對(duì)象訪問:但是classRoom是三個(gè)對(duì)象共享的
下面這個(gè)例子詳細(xì)說明共享性:
class Student{
public String name;
public String gender;
public int age;
public double score;
public static int classroom = 1;
}
public class One {
public static void main(String[] args) {
Student student1 = new Student();
Student student2 = new Student();
Student student3 = new Student();
student1.classroom++;
student2.classroom++;
student3.classroom--;
Student.classroom++;
System.out.println(Student.classroom);
}
}
你覺得輸出結(jié)果是多少呢?答案是3。
因?yàn)閏lassroom不依賴于對(duì)象而存在,依賴于類而存在。
2.static修飾成員方法
【靜態(tài)方法特性】
- 不屬于某個(gè)具體的對(duì)象,是類方法
- 可以通過對(duì)象調(diào)用,也可以通過類名.靜態(tài)方法名(…)方式調(diào)用,更推薦使用后者
- 不能在靜態(tài)方法中訪問任何非靜態(tài)成員變量
- 靜態(tài)方法中不能調(diào)用任何非靜態(tài)方法,因?yàn)榉庆o態(tài)方法有this參數(shù),在靜態(tài)方法中調(diào)用時(shí)候無法傳遞this引用
三、代碼塊
1.代碼塊概念以及分類
使用 {} 定義的一段代碼稱為代碼塊。根據(jù)代碼塊定義的位置以及關(guān)鍵字,又可分為以下四種:
1.普通代碼塊
2.構(gòu)造塊
3.靜態(tài)塊
4.同步代碼塊
2.普通代碼塊
普通代碼塊:定義在方法中的代碼塊
public class Main{
public static void main(String[] args) {
{ //直接使用{}定義,普通方法塊
int x = 10 ;
System.out.println("x1 = " +x);
}
int x = 100 ;
System.out.println("x2 = " +x);
}
}
// 執(zhí)行結(jié)果
x1 = 10
x2 = 100
3.構(gòu)造代碼塊靜態(tài)代碼塊實(shí)例代碼塊
如何定義:
{
this.classroom = 114;
System.out.println("調(diào)用了實(shí)例化代碼塊");
}
static{
classroom = 115;
System.out.println("調(diào)用了靜態(tài)代碼塊,一般用來初始化成員變量");
}
public Student1(String name, String gender, int age) {
this.name = name;
this.gender = gender;
this.age = age;
System.out.println("構(gòu)造函數(shù)生成了");
}
靜態(tài)代碼塊隨類的生成而生成:
class Student1{
public String name;
public String gender;
public int age;
private static int classroom = 113;
public static int getClassroom(){
return classroom;
}
{
this.classroom = 114;
System.out.println("調(diào)用了實(shí)例化代碼塊");
}
static{
classroom = 115;
System.out.println("調(diào)用了靜態(tài)代碼塊,一般用來初始化成員變量");
}
public Student1(String name, String gender, int age) {
this.name = name;
this.gender = gender;
this.age = age;
System.out.println("構(gòu)造函數(shù)生成了");
}
}
public class Two {
public static void main(String[] args) {
System.out.println(Student1.getClassroom());
}
}

這段代碼中只有靜態(tài)代碼塊生成了。
再來看下面這段代碼:
class Student1{
public String name;
public String gender;
public int age;
private static int classroom = 113;
public static int getClassroom(){
return classroom;
}
{
this.classroom = 114;
System.out.println("調(diào)用了實(shí)例化代碼塊");
}
static{
classroom = 115;
System.out.println("調(diào)用了靜態(tài)代碼塊,一般用來初始化成員變量");
}
public Student1(String name, String gender, int age) {
this.name = name;
this.gender = gender;
this.age = age;
System.out.println("構(gòu)造函數(shù)生成了");
}
}
public class Two {
public static void main(String[] args) {
Student1 student = new Student1("zhangsan","男",5);
System.out.println(student.getClassroom());
}
}


靜態(tài)代碼塊只會(huì)執(zhí)行一次,實(shí)例代碼塊和構(gòu)造代碼塊執(zhí)行次數(shù)和定義的對(duì)象個(gè)數(shù)相同。
即:
注意事項(xiàng)
靜態(tài)代碼塊不管生成多少個(gè)對(duì)象,其只會(huì)執(zhí)行一次
靜態(tài)成員變量是類的屬性,因此是在JVM加載類時(shí)開辟空間并初始化的
如果一個(gè)類中包含多個(gè)靜態(tài)代碼塊,在編譯代碼時(shí),編譯器會(huì)按照定義的先后次序依次執(zhí)行(合并)
實(shí)例代碼塊只有在創(chuàng)建對(duì)象時(shí)才會(huì)執(zhí)行
四、對(duì)象的打印
在開發(fā)中,我們經(jīng)常需要打印對(duì)象信息來調(diào)試或展示,但直接打印對(duì)象會(huì)得到不理想的結(jié)果,這就需要重寫toString()方法
public class Person {
String name;
String gender;
int age;
public Person(String name, String gender, int age) {
this.name = name;
this.gender = gender;
this.age = age;
}
public static void main(String[] args) {
Person person = new Person("Jim","男", 18);
System.out.println(person);
}
}

這段代碼打印的結(jié)果是person這個(gè)對(duì)象的地址信息
如果想要默認(rèn)打印對(duì)象中的屬性該如何處理呢?答案:重寫toString方法即可。
public class Person {
String name;
String gender;
int age;
public Person(String name, String gender, int age) {
this.name = name;
this.gender = gender;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", gender='" + gender + '\'' +
", age=" + age +
'}';
}
public static void main(String[] args) {
Person person = new Person("Jim","男", 18);
System.out.println(person);
}
}
toString方法也可以按照之前學(xué)習(xí)的一鍵生成構(gòu)造方法的方式來快速生成
總結(jié)
?本文介紹了類和對(duì)象的四個(gè)進(jìn)階知識(shí)點(diǎn):?
封裝通過private隱藏?cái)?shù)據(jù),用getter/setter控制訪問,保障數(shù)據(jù)安全和代碼可維護(hù)性。?
static 成員屬于類而非對(duì)象,適用于共享數(shù)據(jù)和工具方法,通過類名.成員訪問。?
代碼塊分為靜態(tài)代碼塊(類加載時(shí)執(zhí)行)和實(shí)例代碼塊(對(duì)象創(chuàng)建時(shí)執(zhí)行),用于初始化操作。?
對(duì)象打印需重寫toString()方法,自定義屬性輸出格式,提升調(diào)試效率。?
這些知識(shí)點(diǎn)是面向?qū)ο缶幊痰暮诵?,掌握它們能幫助你編寫更?guī)范、高效的 Java 代碼。下一階段,我們將學(xué)習(xí)繼承和多態(tài),進(jìn)一步完善面向?qū)ο蟮闹R(shí)體系。
到此這篇關(guān)于javaSE類和對(duì)象進(jìn)階用法的文章就介紹到這了,更多相關(guān)javaSE類和對(duì)象內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
如何使用Jackson和JSON Pointer查詢解析任何JSON節(jié)點(diǎn)
本文介紹了JSON Pointer是字符串表達(dá)式,可以非常方便解析復(fù)雜JSON節(jié)點(diǎn)值,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-09-09
IDEA查看所有的斷點(diǎn)(Breakpoints)并關(guān)閉的方式
我們?cè)谑褂肐DEA開發(fā)Java應(yīng)用時(shí),基本上都需要進(jìn)行打斷點(diǎn)的操作,這方便我們排查BUG,也方便我們查看設(shè)計(jì)的是否正確,不過有時(shí)候,我們不希望進(jìn)入斷點(diǎn),所以我們需要快速關(guān)閉所有斷點(diǎn),故本文給大家介紹了IDEA查看所有的斷點(diǎn)(Breakpoints)并關(guān)閉的方式2024-10-10
詳解springboot項(xiàng)目帶Tomcat和不帶Tomcat的兩種打包方式
這篇文章主要介紹了詳解springboot項(xiàng)目帶Tomcat和不帶Tomcat的兩種打包方式,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2020-09-09
Mybatis中SqlSession下的四大對(duì)象之執(zhí)行器(executor)
mybatis中sqlsession下的四大對(duì)象是指:executor, statementHandler,parameterHandler,resultHandler對(duì)象。這篇文章主要介紹了Mybatis中SqlSession下的四大對(duì)象之執(zhí)行器(executor),需要的朋友可以參考下2019-04-04
Springboot詳細(xì)講解RocketMQ實(shí)現(xiàn)順序消息的發(fā)送與消費(fèi)流程
RocketMQ作為一款純java、分布式、隊(duì)列模型的開源消息中間件,支持事務(wù)消息、順序消息、批量消息、定時(shí)消息、消息回溯等,本篇我們了解如何實(shí)現(xiàn)順序消息的發(fā)送與消費(fèi)2022-06-06

