-1-2 java 面向物件基本概念 封裝繼承多型 變數 this super static 靜態變數 匿名物件 值傳遞 初始化過程 程式碼塊 final關鍵字 抽象類 介面 區別 多型 包 訪問許可權 內部類 匿名內部類 == 與 equal
java是純粹的面向物件的語言
也就是萬事萬物皆是物件
程式是物件的集合,他們通過傳送訊息來相互通訊
每個物件都有自己的由其他的物件所構建的儲存,也就是物件可以包含物件
每個物件都有它的型別 也就是類
某一特定型別的所有物件都可以接收相同的訊息,因為同一類事物有共同的特性
面向物件開發
•就是不斷的建立物件,使用物件,指揮物件做事情。
面向物件設計
•其實就是在管理和維護物件之間的關係。
面向物件特徵
•封裝(encapsulation)
•繼承(inheritance)
•多型(polymorphism)
現實應用場景終歸是要解決問題,面向過程的語言,是一個方法伴隨著另一個方法的呼叫
隨著應用規模的不斷變大,顯然軟體程式碼管理變得更加困難
面向物件把功能邏輯封裝到類本身,用物件去呼叫功能 持有資料,結構更加自然,也更符合人們的思維習慣
也就是說java中類 和物件 是劃分邏輯功能的具體單位
面向物件的語言中,都會有類這個概念,一類事物他們有共同的屬性和行為
java中描述事物通過類的形式體現,類是具體事物的抽象,概念上的定義。
物件即是該類事物實實在在存在的個體。
類:是一組相關的屬性和行為的集合
物件:是該類事物的具體體現
成員變數與區域性變數
在類中的位置不同
•成員變數 類中方法外
•區域性變數 方法內或者方法宣告上
在記憶體中的位置不同
•成員變數 堆記憶體
•區域性變數 棧記憶體
生命週期不同
•成員變數 隨著物件的存在而存在,隨著物件的消失而消失
•區域性變數 隨著方法的呼叫而存在,隨著方法的呼叫完畢而消失
初始化值不同
•成員變數 有預設的初始化值
•區域性變數 沒有預設的初始化值,必須先定義,賦值,才能使用。
this:代表所在類的物件引用
記住:
•方法被哪個物件呼叫,this就代表那個物件
什麼時候使用this呢?
•區域性變數隱藏成員變數
static關鍵字
可以修飾成員變數和成員方法
static關鍵字特點
•隨著類的載入而載入
•優先於物件存在
•被類的所有物件共享
•這也是我們判斷是否使用靜態關鍵字的條件
•可以通過類名呼叫
static關鍵字注意事項
•在靜態方法中是沒有this關鍵字的
•靜態方法只能訪問靜態的成員變數和靜態的成員方法
靜態變數與成員變數
所屬不同
•靜態變數屬於類,所以也稱為為類變數
•成員變數屬於物件,所以也稱為例項變數(物件變數)
記憶體中位置不同
•靜態變數儲存於方法區的靜態區
•成員變數儲存於堆記憶體
記憶體出現時間不同
•靜態變數隨著類的載入而載入,隨著類的消失而消失
•成員變數隨著物件的建立而存在,隨著物件的消失而消失
呼叫不同
•靜態變數可以通過類名呼叫,也可以通過物件呼叫
•成員變數只能通過物件名呼叫
匿名物件
匿名物件:就是沒有名字的物件。
•是物件的一種簡化表示形式
匿名物件的兩種使用情況
•物件呼叫方法僅僅一次的時候
•作為實際引數傳遞
值傳遞
java中全部都是值傳遞 引用型別傳遞的也是值 只不過是地址
初始化過程
Student s = new Student();在記憶體中做了哪些事情?
•載入Student.class檔案進記憶體
•在棧記憶體為s開闢空間
•在堆記憶體為學生物件開闢空間
•對學生物件的成員變數進行預設初始化
•對學生物件的成員變數進行顯示初始化
•通過構造方法對學生物件的成員變數賦值
•學生物件初始化完畢,把物件地址賦值給s變數
封裝
封裝概述
•是指隱藏物件的屬性和實現細節,僅對外提供公共訪問方式。
好處:
•隱藏實現細節,提供公共的訪問方式
•提高了程式碼的複用性
•提高安全性。
封裝原則:
•將不需要對外提供的內容都隱藏起來。
•把屬性隱藏,提供公共方法對其訪問。
構造方法
特點:
1.函式名與類名相同
2.不用定義返回值型別
3.沒有具體的返回值。
作用:
給物件進行初始化。
注意:
1.預設建構函式的特點,如果自建將會失去預設,需要的話必須顯式
2.多個建構函式是以過載的形式存在的。
程式碼塊
•在Java中,使用{}括起來的程式碼被稱為程式碼塊,根據其位置和宣告的不同,可以分為區域性程式碼塊,構造程式碼塊,靜態程式碼塊,同步程式碼塊(多執行緒講解)。
•區域性程式碼塊
•在方法中出現;限定變數生命週期,及早釋放,提高記憶體利用率
•構造程式碼塊
•在類中方法外出現;多個構造方法方法中相同的程式碼存放到一起,每次呼叫構造都執行,並且在構造方法前執行
•靜態程式碼塊 在類中方法外出現,加了static修飾
•在類中方法外出現,並加上static修飾;用於給類進行初始化,在載入的時候就執行,並且值執行一次。
執行順序 靜態程式碼塊 > 構造程式碼塊 > 構造方法
private關鍵字
(1)私有的意義,可以修飾成員變數和成員方法
(2)特點:
被private修飾的後的成員只能在本類中被訪問
(3)private的應用:
以後再寫一個類的時候:
把所有的成員變數給private了
提供對應的getXxx()/setXxx()方法
繼承
多個類中存在相同屬性和行為時,
將這些內容抽取到單獨一個類中,那麼多個類無需再定義這些屬性和行為,只要繼承那個類即可。
多個類可以稱為子類,單獨這個類稱為父類或者超類。
子類可以直接訪問父類中的非私有的屬性和行為。
通過extends 關鍵字讓類與類之間產生繼承關係。
•class SubDemo extendsDemo{}
繼承的出現提高了程式碼的複用性。
繼承的出現讓類與類之間產生了關係,提供了多型的前提。
Java只支援單繼承,不支援多繼承。
•一個類只能有一個父類,不可以有多個父類。
•class SubDemo extends Demo{} //ok
•class SubDemo extends Demo1,Demo2...//error
Java支援多層繼承(繼承體系)
•class A{}
•class B extends A{}
•class C extends B{}
定義繼承需要注意:
•不要僅為了獲取其他類中某個功能而去繼承
繼承缺點:
1,讓類的耦合性增強。這樣某個類的改變,就會影響其他和該類相關的類。
原則:低耦合,高內聚。
耦合:類與類的關係
內聚:自己完成某件事情的能力
2.打破了封裝性
super
this代表本類物件的引用
•類與類之間要有所屬( " is a " )關係,xx1是xx2的一種。
super代表父類的記憶體空間的標識。
當子父類出現同名成員時,可以用super進行區分
子類要呼叫父類建構函式時,可以使用super語句。
方法覆蓋 override
子類中出現與父類一模一樣的方法時,會出現覆蓋操作,也稱為重寫或者複寫。
父類中的私有方法不可以被覆蓋。
在子類覆蓋方法中,繼續使用被覆蓋的方法可以通過super.函式名獲取。
覆蓋注意事項:
•覆蓋時,子類方法許可權一定要大於等於父類方法許可權
•靜態只能覆蓋靜態。
覆蓋的應用:
•當子類需要父類的功能,而功能主體子類有自己特有內容時,可以複寫父類中的方法,
這樣,即沿襲了父類的功能,又定義了子類特有的內容。
子類例項化過程
子類中所有的建構函式預設都會訪問父類中空引數的建構函式
因為每一個建構函式的第一行都有一條預設的語句super();
子類會具備父類中的資料,所以要先明確父類是如何對這些資料初始化的。
當父類中沒有空引數的建構函式時,子類的建構函式必須通過this或者super語句指定要訪問的建構函式。
final關鍵字
final可以修飾類,方法,變數。
final修飾的類不可以被繼承。
final修飾的方法不可以被覆蓋。
final修飾的變數是一個常量。只能被賦值一次。
內部類只能訪問被final修飾的區域性變數。
1,變數
a:基本型別 值不能發生改變
b:引用型別 地址值不能發生改變,但是物件的內容是可以改變的
2,初始化時機
a:只能初始化一次。
b:常見的給值方式
定義的時候。(推薦)
構造方法中。
抽象類
抽象定義:
•抽象就是從多個事物中將共性的,本質的內容抽取出來。
抽象類:
•Java中可以定義沒有方法體的方法,該方法的具體實現由子類完成,該方法稱為抽象方法,
包含抽象方法的類就是抽象類。
抽象方法的由來:
•多個物件都具備相同的功能,但是功能具體內容有所不同
那麼在抽取過程中,只抽取了功能定義,並未抽取功能主體,那麼只有功能宣告,沒有功能主體的方法稱為抽象方法。
抽象類和抽象方法必須用abstract關鍵字來修飾。
抽象方法只有方法宣告,沒有方法體,定義在抽象類中。
•格式:修飾符 abstract 返回值型別 函式名(引數列表) ;
抽象類不可以被例項化,也就是不可以用new建立物件。原因如下:
•抽象類是具體事物抽取出來的,本身是不具體的,沒有對應的例項。
•而且抽象類即使建立了物件,呼叫抽象方法也沒有意義。
抽象類通過其子類例項化,而子類需要覆蓋掉抽象類中所有的抽象方法後才可以建立物件,否則該子類也是抽象類。
介面
格式:
interface {}
介面中的成員修飾符是固定的。
•成員常量:public static final
•成員函式:public abstract
•介面中的成員都是public的。
沒有構造方法
介面的出現將“多繼承”通過另一種形式體現出來,即“多實現”。
介面是對外暴露的規則。
介面是程式的功能擴充套件。
介面的出現降低耦合性。
介面可以用來多實現。
類與介面之間是實現關係,而且類可以繼承一個類的同時實現多個介面。
介面與介面之間可以有繼承關係。
•類實現介面用implements表示
•格式:
class 類名 implements 介面名 {}
•介面不能例項化 那麼,介面如何例項化呢?
按照多型的方式,由具體的子類例項化。其實這也是多型的一種,介面多型。
•介面的子類 要麼是抽象類 要麼重寫介面中的所有抽象方法
類與類,類與介面以及介面與介面的關係
類與類
•繼承關係,只能單繼承,但是可以多層繼承
類與介面
•實現關係,可以單實現,也可以多實現。還可以在繼承一個類的同時實現多個介面
介面與介面
•繼承關係,可以單繼承,也可以多繼承
多型
某一類事物的多種存在形態
程式中體現:
父類或者介面的引用指向或者接收自己的子類物件。
好處和作用:
多型的存在提高了程式的擴充套件性和後期可維護性
前提:
•需要存在繼承或者實現關係
•要有覆蓋操作
•有父類或者父介面引用指向子類物件。
包
對類檔案進行分類管理。
給類提供多層名稱空間。
寫在程式檔案的第一行。
類名的全稱的是 包名.類名。
包也是一種封裝形式。
定義包的格式
•package 包名;
•多級包用.分開即可
注意事項:
•package語句必須是程式的第一條可執行的程式碼
•package語句在一個java檔案中只能有一個
•如果沒有package,預設表示無包名
類:
•預設default,public,final,abstract
•我們自己定義:public居多
成員變數:
•四種許可權修飾符均可,final,static
•我們自己定義:private居多
構造方法:
•四種許可權修飾符均可,其他不可
•我們自己定義:public 居多
成員方法:
•四種許可權修飾符均可,fianl,static,abstract
•我們自己定義:public居多
import
簡化類名。
一個程式檔案中只有一個package,可以有多個import。
用來導包中的類,不匯入包中的包。
內部類
將一個類定義在另一個類的裡面,對裡面那個類就稱為內部類(內建類,巢狀類)。
訪問特點:
•內部類可以直接訪問外部類中的成員,包括私有成員。
•而外部類要訪問內部類中的成員必須要建立內部類的物件。
成員內部類 區域性內部類
內部類定義在成員位置上
•可以被private static成員修飾符修飾。
•被static修飾的內部類只能訪問外部類中的靜態成員。
成員內部類不是靜態的:
外部類名.內部類名 物件名 = 外部類名.new 內部類名();
成員內部類是靜態的:
外部類名.內部類名 物件名 = new 外部類名.內部類名();
內部類定義在區域性位置上
•也可以直接訪問外部類中的成員。
•同時可以訪問所在區域性中的區域性變數,但必須是被final修飾的。
內部類訪問外部類屬性 外部類名稱.this.屬性名
匿名內部類
就是內部類的簡化寫法。
前提:
•內部類可以繼承或實現一個外部類或者介面。
格式為:
•new外部類名或者介面名(){
覆蓋類或者介面中的程式碼,(也可以自定義內容。)
}
簡單理解:
•就是建立一個帶內容的外部的類或者介面的子類匿名物件。
Object類
(1)Object是類層次結構的根類,所有的類都直接或者間接的繼承自Object類。
(2)Object類的構造方法有一個,並且是無參構造
這其實就是理解當時我們說過,子類構造方法預設訪問父類的構造是無參構造
(3)要掌握的方法:
toString()
返回物件的字串表示,預設是由類的全路徑+'@'+雜湊值的十六進位制表示。
這個表示其實是沒有實際意義的,一般子類都會重寫該方法。
equals()
比較兩個物件是否相同。預設情況下,比較的是地址值是否相同。
而比較地址值是沒有意義的,所以,一般子類也會重寫該方法。
(4)要了解的方法:
hashCode() 返回物件的雜湊值。不是實際地址值,可以理解為地址值。
getClass() 返回物件的位元組碼檔案物件
finalize() 用於垃圾回收,在不確定的時間
clone() 可以實現物件的克隆,包括成員變數的資料複製,但是它和兩個引用指向同一個物件是有區別的。
(5)兩個注意問題;
直接輸出一個物件名稱,其實預設呼叫了該物件的toString()方法。
==和equals()的區別?
==
基本型別:比較的是值是否相同
引用型別:比較的是地址值是否相同
equals()
只能比較引用型別。預設情況下,比較的是地址值是否相同。
但是,我們可以根據自己的需要重寫該方法。