OOP之封裝全過程(Java)
面向?qū)ο笳Z言的三大特性:封裝、繼承、多態(tài)。本篇文章將講述封裝有關(guān)...何為封裝?! 簡而言之就是套殼屏蔽細節(jié)...
概念
封裝:將數(shù)據(jù)和操作數(shù)據(jù)的方法進行有機結(jié)合,隱藏對象的屬性和實現(xiàn)細節(jié),僅對外公開接口來和對象進行交互。
注:接口有兩層含義 -> ①.方法 ②.真正的接口(語法);此處加粗的接口為第一層含義
如下列代碼,將成員變量name,age用private修飾后,外界不可直接獲取、修改name和age,那么通過創(chuàng)建公開的方法getName()、setName()、getAge()...來對封裝的成員變量進行操作
public class Person {
private String name;
private int age;
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
}Person person = new Person();
person.setName("張三");
System.out.println(person.getName());//打印張三- 快捷生成get()/set()方法 -->
- 鼠標右鍵Generate --> Getter(只要get())
- Setter(只要set()) --> 可選中全部屬性
- Getter and Setter --> ok --> 會自動生成get()/set()
因此,從語法上來說,封裝就是被private修飾的成員變量或者成員方法,且只能在當(dāng)前類當(dāng)中使用。
訪問限定符
JAVA中主要通過類和訪問權(quán)限來實現(xiàn)封裝:類可以將數(shù)據(jù)以及封裝數(shù)據(jù)的方法結(jié)合在一起,而訪問權(quán)限用來控制方法或者字段能否直接在類外使用。
JAVA提供了四種訪問限定符:
| No | 范圍 | private | default | protected | public |
| 1 | 同一包中的同一類 | ? | ? | ? | ? |
| 2 | 同一包中的不同類 | ? | ? | ? | |
| 3 | 不同包中的子類 | ? | ? | ||
| 4 | 不同包中的非子類 | ? |
private: 私有的(只有自己知道,其他人都不知道)default: 默認的,包訪問權(quán)限 (!不要在成員/方法前加default,什么都不寫即為默認)protected: 受保護的 (主要用在繼承中,繼承部分詳細介紹)public: 公有的(哪都能用)
注:
- ①.訪問權(quán)限除了可以限定類中成員的可見性,也可以控制類的可見性
- ②.一般情況下,成員變量設(shè)置為private,成員方法設(shè)置為public
封裝擴展之包
包的概念
為了更好的組織和管理類,把多個類收集在一起成為一組,稱為軟件包。
導(dǎo)入包中的類
使用import語句導(dǎo)入包
- eg:專門組織管理和操作數(shù)組相關(guān)的類
import java.util.Arrays
包是對類、接口等的封裝機制的體現(xiàn),是一種對類或者接口等的很好的組織方式。包還有一個重要的作用:在同一個工程中允許存在相同名稱的類,只要處在不同的包中即可。
例如,Date類既存在于java.util包中,也存在于java.sql包中
import java.util.Date; import java.sql.Date;
如果需要使用java.util中的其他類,可以使用通配符*
import java.util.*
(只要是util底下的所有類,都能夠進行適配)
但是,更建議顯式的指定要導(dǎo)入的類名,否則還是容易出現(xiàn)沖突的情況。
import java.util.*;
import java.sql.*;
public class Test{
public static void main(String[] args){
//util和sql中都存在一個Date這樣的類,此時就會出現(xiàn)歧義,編譯出錯
Date date = new Date();
System.out.println(date.getTime());
}
}
//編譯出錯
//Error:(5,9)java:對Date的引用不準確
//java.sql中的類java.sql.Date和java.util中的類java.util.Date都匹配在這種情況下需要使用完整的類名
java.util.Date date = new java.util.Date();
- 使用import static導(dǎo)入包中靜態(tài)的方法和字段
import static java.lang.Math.*; //導(dǎo)入導(dǎo)入這個類中的所有靜態(tài)方法
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 redult = sqrt( pow(x,2) + pow(y,2) );
System.out.println(result);
}
}*歸根結(jié)底,包就是個文件夾,里面有很多類,類中有很多方法...
自定義包
基本規(guī)則
- 在文件的最上方加上一個package語句指定該代碼在哪個包中.
- 包名需要盡量指定成唯一的名字,通常會用公司的域名的顛倒形式(eg: com.baidu.www;)
- 包名要和代碼路徑相匹配。eg:創(chuàng)建com.baidu.demo1的包,那么會存在一個對應(yīng)的路徑 com/baidu/demo1來存儲代碼
- 如果一個類沒有package語句,則該類被放到一個默認包中.
操作步驟
1.先創(chuàng)建一個包:右鍵src --> 新建 --> 包
2.在彈出的對話框中輸入包名(小寫)
3.在包中創(chuàng)建類:右鍵包名 --> 新建 --> 類,然后輸入類名即可
4.此時可以看到磁盤上的目錄結(jié)構(gòu)已經(jīng)被IDEA自動創(chuàng)建出來了
5.同時可以看到,在新創(chuàng)建的Test.java文件的最上方,就出現(xiàn)了一個package語句
static成員
概念
使用學(xué)生類實例化三個對象s1、s2、s3,每個對象都有自己特有的姓名、性別、年齡、學(xué)分績點等成員信息,這些信息就是對不同學(xué)生進行描述的。
- 如下所示:
public class Student{
public static void main(String[] args){
Student s1 = new Student("李雷","男",18,3.8);
Student s2 = new Student("韓梅梅","女",19,4.0);
Student s3 = new Student("Jim","男",18,2.6);
}
}假設(shè)三個同學(xué)是同一班的,那么他們上課肯定是在同一個教室,既然在同一個教室,能否在類中再加一個成員變量,來保存同學(xué)上課時的教室呢?!
答案是不行的 --> 在Student類中定義的成員變量,每個對象都會包含一份(稱為實例變量),因為需要使用這些信息來描述具體的學(xué)生。而現(xiàn)在要表示上課的教室,這個教室的屬性并不需要每個學(xué)生對象中都存儲一份,而是需要讓所有的學(xué)生來共享。
在JAVA中,被static修飾的成員,稱之為靜態(tài)成員,也可以稱為類成員,其不屬于某個具體的對象,是所有對象所共享的。
static修飾成員變量
static修飾的成員變量,稱為靜態(tài)成員變量
[靜態(tài)成員變量特性]:
- ①.不屬于某個具體的對象,是類的屬性,所有對象共享的,不存儲在某個對象的空間中(最大特性,即靜態(tài)成員變量不屬于對象)
- ②.既可以通過對象訪問(會出現(xiàn)警告),也可以通過類名訪問(推薦)
- ③.類變量存儲在方法區(qū)當(dāng)中
- ④.生命周期伴隨類的一生(隨類的加載而創(chuàng)建,隨類的卸載而銷毀)
public class Student{
public static String classRoom = "101";
public static void main(String[] args){
//靜態(tài)成員變量可以直接通過類名訪問
System.out.println(Student.classRoom);
}
}static修飾成員方法
一般類中的數(shù)據(jù)成員都設(shè)置為private,而成員方法設(shè)置為public,那設(shè)置之后,Student類中classroom屬性如何在類外訪問呢?!
public class Student{
private static String classRoom = "101";
}
public class TestStudent{
public static void main(String[] args){
System.out.println(Student.classRoom);
}
}
//Error:(10,35)java:classRoom在extend01.Student中是private控制JAVA中,被static修飾的成員方法稱為靜態(tài)成員方法,是類的方法,不是某個對象所特有的。靜態(tài)成員一般是通過靜態(tài)方法來訪問的。
public class Student{
private static String classRoom = "101";
public static String getClassRoom(){
return classRoom;
}
}public class TestStudent{
public static void main(String[] args){
System.out.println(Student.getClassRoom());
}
}[靜態(tài)方法特性]:
①.不屬于某個具體的對象,是類方法
② .可以通過對象調(diào)用,也可以通過類名.靜態(tài)方法名(...)方式調(diào)用(更推薦)
③.不能在靜態(tài)方法中訪問任何非靜態(tài)成員變量
④ .靜態(tài)方法中不能調(diào)用任何非靜態(tài)方法,因為非靜態(tài)方法有this參數(shù),在靜態(tài)方法中調(diào)用時候無法傳遞this引用
- eg:
public static void func(){
System.out.println("靜態(tài)的!");
System.out.println(this.name + "。。。"); //error
}-->name的調(diào)用需要對象的引用來調(diào)用,而func()這個靜態(tài)方法直接通過類名就能調(diào)用,不依賴于對象
--> 因此,在靜態(tài)方法中,不能調(diào)用非靜態(tài)的成員變量或者非靜態(tài)的成員方法;靜態(tài)方法當(dāng)中不包含this
static成員變量初始化
靜態(tài)成員變量的初始化分為兩種:就地初始化、靜態(tài)代碼塊初始化
Ⅰ.就地初始化
就地初始化指的是:在定義時直接給出初始值
public class Student{
private String name;
private String gender;
//...
private static String classRoom = "101";
}Ⅱ.靜態(tài)代碼塊初始化
什么是代碼塊?!!
代碼塊概念及分類
使用{}定義的一段代碼稱為代碼塊,可分為以下四種:普通代碼塊、*構(gòu)造塊、*靜態(tài)塊、同步代碼塊
普通代碼塊
定義在方法中的代碼塊(很少見)
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);
}
}
//x1 = 10
//x2 = 100構(gòu)造代碼塊
構(gòu)造塊:定義在類中的代碼塊(不加修飾符),也叫:實例代碼塊。
構(gòu)造代碼塊
- 一般用于初始化實例成員變量
public class Student{
//實例成員變量
private String name;
private String gender;
{
this.name = "小明";
this.gender = "男";
}
public void show(){
System.out.println("name:" + name + "gender:" + gender);
}
}public class Main{
public static void main(String[] args){
Student stu = new Student();
stu.show();
}
}
//name:小明gender:男注:構(gòu)造(實例)代碼塊只有在創(chuàng)建對象時才會執(zhí)行
靜態(tài)代碼塊
使用static定義的代碼塊稱為靜態(tài)代碼塊。一般用于初始化靜態(tài)成員變量。
public class Student{
private static String classRoom;
static{
classRoom = "101";
}
}注:
- 靜態(tài)代碼塊不管生成多少個對象,其只會執(zhí)行一次
- 靜態(tài)成員變量是類的屬性,因此是在JVM加載類時開辟空間并初始化的
- 如果一個類中包含多個靜態(tài)代碼塊,在編譯代碼時,編譯器會按照定義的先后次序依次執(zhí)行(合并)
同步代碼塊
具體介紹在后續(xù)多線程部分...
總結(jié)
①.執(zhí)行順序:靜態(tài)代碼塊 --> 構(gòu)造代碼塊 --> 對應(yīng)的構(gòu)造方法
②.靜態(tài)代碼塊只執(zhí)行一次
以上為個人經(jīng)驗,希望能給大家一個參考,也希望大家多多支持腳本之家。
相關(guān)文章
Java多態(tài)和實現(xiàn)接口的類的對象賦值給接口引用的方法(推薦)
下面小編就為大家?guī)硪黄狫ava多態(tài)和實現(xiàn)接口的類的對象賦值給接口引用的方法(推薦)。小編覺得挺不錯的,現(xiàn)在就分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-02-02
關(guān)于Springboot2.x集成lettuce連接redis集群報超時異常Command timed out afte
這篇文章主要介紹了Springboot2.x集成lettuce連接redis集群報超時異常Command timed out after 6 second(s),本文通過實例代碼給大家介紹的非常詳細,需要的朋友可以參考下2021-03-03
SpringBoot集成Serverless的實現(xiàn)示例
本文主要介紹了SpringBoot集成Serverless的實現(xiàn)示例,文中通過示例代碼介紹的非常詳細,對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2026-04-04
Java transient 關(guān)鍵字詳解及實例代碼
本文章向大家介紹Java transient關(guān)鍵字的使用方法和實例,包括的知識點有transient的作用、transient使用小結(jié)、transient使用細節(jié),需要的朋友可以參考一下2016-12-12
基于Springboot商品進銷存管理系統(tǒng)的設(shè)計與實現(xiàn)
本項目基于springboot實現(xiàn)一個進銷存管理系統(tǒng),主要用戶開設(shè)網(wǎng)店的相關(guān)商品的進貨、銷售、庫存的管理,功能比較完整,需要的可以參考一下2022-08-08
Java中List常用操作比for循環(huán)更優(yōu)雅的寫法示例
List是Java中比較常用的集合類,關(guān)于List接口有很多實現(xiàn)類,下面這篇文章主要給大家介紹了關(guān)于Java中List常用操作比for循環(huán)更優(yōu)雅的寫法,需要的朋友可以參考下2021-11-11
使用mybatis-plus分頁出現(xiàn)兩個Limit的問題解決
在使用MyBatis-Plus進行分頁查詢時,可能會遇到查詢SQL中出現(xiàn)兩個limit語句的問題,這通常是由于在多個模塊中重復(fù)引入了MyBatis-Plus的分頁插件所導(dǎo)致的,下面就來介紹一下如何解決,感興趣的可以了解一下2024-10-10

