04-java面向物件
java面向物件
面向過程開發:
其實就是面向具體的每一個步驟和過程,把每一個步驟和過程完成,然後有這些功能方法相互呼叫,完成需求
代表語言:C語言
面向物件是基於面向過程的程式設計思想
面向過程:強調的是每一個功能的步驟
面向物件:強調的是物件,然後由物件去呼叫功能
面向物件的特點:
1:是一種更符合我們思想習慣的思想
2:可以將複雜問題簡單化
3:將我們從執行者變成指揮者
舉例:
買電腦:
面向過程: 瞭解電腦
瞭解需求
對應引數資訊
去電腦城買電腦
討價還價
買回電腦
面向物件:
我要買電腦,叫人去給我買 ,別人給我買回來
洗衣服:
面向過程:脫衣服 找洗衣盆 放洗衣粉 加點水 戳衣服 清洗衣服 擰乾 晾衣服
面向物件:脫衣服 開啟洗衣機 扔衣服 一鍵即可 晾起來
面向物件開發:
就是不斷的建立物件,使用物件,指揮物件做事情
面向物件設計:
其實就是在管理與維護物件之間的關係
面向物件特徵:
封裝
繼承
多型
現實世界如何描述一個事物:
學生
姓名,性別 年齡
學習 吃飯 水蕨
屬性:該事物的資訊
行為:該事物能夠做什麼
學習程式語言,是為了模擬現實世界的事物的
java中最基本的單位是:類
將事物用類體現出來
事物和類的對應關係:
事物: 類:
屬性 成員變數
行為 成員方法
類:是一組相關的屬性和行為的集合。是一個抽象的概念
物件:是該類事物的具體表現形式。具體存在的個體
舉例;
學生:類
班長:物件
定義類:其實對應類就是定義類的成員變數與成員方法
如何使用:
建立物件使用
如何建立:
格式:類名 物件名 = new 類名()
如何使用成員變數:
物件名.變數名
如何使用成員方法:
物件名.方法名(引數)
成員變數與成員變數的區別:
1:在類中的的位置不同
成員變數:在類中方法外
區域性變數:在方法定義中或者方法宣告
2:在記憶體中的位置不同
成員變數:堆記憶體
區域性變數:棧記憶體
3:生命週期不同
成員變數:隨著物件的建立而存在,隨著物件的消失而消失
區域性變數:隨著方法的呼叫而存在,隨著方法的呼叫完畢而消失
4:初始化值不同:
成員變數:有預設初始化值
區域性變數:沒有預設初始化值,必須定義,賦值,然後才能使用
注意:
區域性變數名稱可以和成員變數名稱一樣,在方法中使用的時候,採用的是就近原則。
形式引數問題:
基本型別:形式引數的改變不影響實際引數
引用型別:形式引數的改變直接影響實際引數
類和陣列是引用型別
匿名物件:
就是沒有名字的物件
new Student();
匿名物件的應用場景:
1:呼叫方法:僅僅呼叫一次時候
呼叫多次時不適合
匿名物件好處:
匿名物件呼叫完就是垃圾,可以被垃圾回收器回收
匿名物件呼叫方法:
new Student().show();
2:匿名物件可以作為實際引數傳遞
測試類一般只建立物件,呼叫方法
資料判斷不可以在成員變數位置,因為做資料校驗,必須依靠邏輯語句,邏輯語句應該定義在方法中
封裝:是指隱藏物件的屬性和實現細節,僅對外提供公共訪問方式
好處:
隱藏實現細節,提供公共的訪問方式
提高了程式碼的複用性
提高安全性
封裝原則:
將不需要對外提高的內容都隱藏起來
把屬性隱藏,提供公共方法對其訪問
private關鍵字:
是一個許可權修飾符
可以修飾成員(成員變數和成員方法)
被private修飾的成員只能在本類中才能訪問
private的應用:
把成員變數用private修飾
提供對應的getXxx()和setXxx()方法
this關鍵字:
代表所在類的物件引用
方法被哪個物件呼叫,this就代表那個物件
什麼時候使用this
區域性變數隱藏成員變數
構造方法作用:
給物件的資料進行初始化
構造方法格式:
方法名與類名相同
沒有返回值型別,連void都沒有
沒有具體的返回值
注意事項:
如果你不提供構造方法,系統會給出預設構造方法
如果你提供了構造方法,系統將不再提供
構造方法也是可以過載的
給成員變數賦值:
1:setXxx()
2:構造方法
類的組成:
成員變數
構造方法
成員方法
方法具體劃分:
根據返回值:
有明確返回值的方法
返回void型別的方法
根據形式引數:
無參方法
帶參方法
一個基本類的標準程式碼寫法:
類:
成員變數
構造方法
無參構造方法
帶參構造方法
成員方法:
getXxx()
setXxx()
給成員變數賦值的方式:
無參構造方法+setXxx()
帶參構造方法
static關鍵字:可以修飾成員變數,也可以修飾成員方法
特點:
1;隨著類的載入而載入
回想main方法
2:優先於物件存在
3:被類的所有物件共享
4:可以通過類名呼叫(推薦使用)
其實它本身也可以通過物件名呼叫
靜態修飾的內容議案稱其為:與類相關的,類成員
注意事項:
1:在靜態方法中沒有this關鍵字的
靜態是隨著類的載入為載入,this是隨著物件的建立而存在
靜態比物件先存在
2:靜態方法只能方法訪問靜態的成員變數和靜態成員方法
靜態方法:
成員變數:只能訪問靜態變數
成員方法:只能方法靜態成員方法
非靜態方法:
成員變數:可以是靜態的木葉可以非靜態的
成員方法:可以是靜態的成員方法,也可以是非靜態的成員方法
靜態變數和成員的區別:
所屬不同
靜態變數屬於類,也稱為類變數
成員變數屬於物件,也稱為例項變數
記憶體中的位置不同:
靜態變數儲存於方法區的靜態區
成員變數儲存於堆記憶體
記憶體出現時間不同:
靜態變數隨著類的載入而載入,隨類的消失而消失
成員變數隨著物件的創而存在,隨著物件的消失而消失
呼叫不同:
靜態變數可以通過類名呼叫,也可以通過物件呼叫
成員變數只能通過物件呼叫
main方法的格式:
public:公共的,訪問許可權是最大的,由於main方法是被jvm呼叫,所以許可權要夠大
static:靜態的,不需要建立物件,通過類名就可以,方便jvm呼叫
void:方法的返回值是返回給呼叫者,而main方法是被jvm呼叫,返回內容給jvm沒有意義
main:是一個常見的方法入口。幾乎語言都是以main作為入口
String[] args:這是一個字串陣列
是早期為了接受鍵盤資料的
格式:java 類名 string... java
測試類的作用:建立其他類的物件,呼叫其它類的功能
在同一個資料夾下,類定義在兩個檔案中和呼叫在一個檔案中其實一樣的
方法改為靜態後,就可以直接通過類名呼叫
如何製作說明書(幫助文件)
1:寫一個工具類
2:對這個類加入文件註釋
3:用工具解析文件註釋
javadoc工具
4:格式
javadoc -d 目錄 -author -version ArryTool.java
目錄:寫一個資料夾的路徑
製作幫助文件出錯:
找不到可以文件化的公共或受保護的類:告訴我們類的許可權不夠
java.lang包下的類不需要匯入,其它的全部需要匯入
看類的版本
類的結構:
成員變數 欄位摘要
構造方法 構造方法摘要
成員方法 方法摘要
學習構造方法
有構造方法 就建立物件
沒有構造方法 成員可能都是靜態的
看方法
左邊:
是否靜態:如果靜態,可以通過類名呼叫
返回值型別:人家 返回什麼,就用什麼接收
右邊:
看方法名:方法名稱不要寫錯
引數列表:人家要什麼,就給什麼;人家要幾個,就給幾個
java程式碼塊:
java中,使用{}括起來的程式碼被稱為程式碼塊
根據其位置和宣告不同,分為:
區域性程式碼塊:區域性位置,用於限定變數的聲生命週期。及早釋放,提高記憶體利用率
構造程式碼塊:在類中的成員位置,用{}括起來的程式碼,每次呼叫構造方法前,都會先執行構造程式碼塊
作用:可以把多個構造方法中的共同程式碼放到一起,對物件進行初始化
靜態程式碼塊:在類中的成員位置,用{}括起來的程式碼,只不過它用static修飾
作用:一般是對類進行初始化
同步程式碼塊:
執行順序:
靜態程式碼塊 -- 構造程式碼塊 -- 構造方法
靜態程式碼塊:執行一次
構造程式碼塊:每次呼叫構造方法都執行
java繼承:
多個類中存在相同屬性和行為時,將這些內容抽取到單獨一個類中,那麼多個類無需再定義這些屬性和行為,只要繼承那個類即可
格式:class 子類名 extends 父類名{}
單獨這個類稱為父類,基類,或者超類;這多個類稱為子類或者派生類
在已經存在類的基礎上,還可以定義自己的新成員
繼承的好處:
提高了程式碼的複用性
多個類相同的成員可以放到一個類中
提高了程式碼的維護性
如果程式碼功能需要修改,修改一處即可
讓類與類之間產生了關係,是多型的前提
其實這也是繼承的一個弊端,類的耦合性很強
開發原則:低耦合,高內聚
耦合:類與類的關係
內聚:就是自己完成事情的能力
java繼承特點:
java只支援單繼承,不支援多繼承
一個類只能有一個父類,不可以有多個父類
java支援多層繼承(繼承體系)
class A{}
class B extends A{}
class C extends C{}
java繼承注意事項:
子類只能繼承父類所有非私有的成員(成員變數,成員方法)
其實這也體現了繼承的另一個弊端,打破了封裝性
子類不能繼承父類的構造方法,但是可以通過super關鍵字去訪問父類構造方法
不要為了部分功能去繼承
繼承其實體現的是一種關係:"is a";採用假設法
繼承中成員變數的關係:在子類中訪問一個變數的查詢順序
名字一樣
·1:在子類中的區域性範圍找,有就使用
2:在子類的成員範圍找,有就使用
3:在父類的成員範圍找,有就使用
4:如果還找不到,就報錯
super的用法和this很像
this代表本類對應的引用
super代表父類儲存空間的標識
用法:
訪問成員變數:
this.成員變數 呼叫本類的成員變數
super.成員變數 呼叫父類的成員變數
訪問構造方法
this(...) 呼叫本類的構造方法
super(...) 呼叫父類的構造方法
訪問成員方法
this.成員方法 呼叫本類的成員方法
super.成員方法 呼叫父類的成員方法
繼承中構造方法的關係:
子類中所有的構造方法預設都會訪問父類中的空引數的構造方法
因為子類會繼承父類中的資料,可能還會是用父類的資料,所以,子類初始化之前,一定要先完成父類資料的初始化
每一個構造方法的第一條語句預設都是:super();
this和super的區別:
繼承中構造方法的注意事項:
如果父類沒有無參構造方法,子類的構造方法會出現什麼現象?子類報錯
怎麼解決
A:在父類中加一個無參構造方法
B:通過使用super關鍵字去顯示的呼叫父類的帶參構造方法
C:子類通過桃紅色去呼叫本類的其他構造方法
子類中一定要有一個去訪問了父類的構造方法,否則父類資料就沒有初始化
注意事項:
this(...)和super(...)必須出現在第一條語句上
繼承中成員方法關係:
子類中的方法和父類中的方法宣告一樣
通過子類呼叫方法:
1:先找子類中,看有沒有這個方法,有就使用
2:再看父類中,有沒有這個方法,有就使用
3:如果沒有就報錯
方法過載:本類中出現的方法名一樣,引數列表不同的方法,與返回值無關
方法重寫:子類中出現了和父類中方法宣告一模一樣的方法宣告,也叫方法覆蓋,方法複寫
方法重寫的應用:
當子類需要父類的功能,而功能主題子類有自己的特有的內容時,可以重寫父類中的方法。這樣,即沿襲了父類的功能,又定義了子類特有的內容。
方法重寫的注意事項:
1:父類中的私有方法不能被重寫:父類私有方法子類無法繼承
2:子類重寫父類方法時,訪問許可權不能更低:最好一致
3:父類靜態方法。子類也必須通過靜態方法進行重寫(其實不算重寫,多型講)
子類重寫方法的時候,最好宣告一模一樣
override:方法重寫
overload:方法過載
API(Apilication Programming Interface)
應用程式程式設計介面(幫助文件)
由於繼承中方法有一個現象:方法重寫
所以父類的功能會被子類覆蓋
java final關鍵字:最終的意思。常見的是它可以修飾類,方法,變數。
final的特點:
1:修飾類的特點:該類不能被繼承。
2:修飾方法的特點:該方法不能被重寫
3:修飾變數的特點:該變數不能被重新賦值。因為這個變數其實是常量
常量:
1:字面值常量:"hell0",10,true
2:自定義常量:final int x = 5;
final修飾區域性變數的問題:
基本型別:基本型別的值不能發生改變
引用型別:引用型別的地址值不能發生改變,該物件的堆記憶體的值可以改變的
final修飾變數的初始化時機:
1:被final修飾的變數只能被賦值一次
2:在構造方法完畢前。(非靜態的常量)
java多型
多型:某一個事物,在不同時刻表現出來的不同狀態
多型前提和體現:
1:有繼承關係或者實現關係
2:有方法重寫
其實沒有也是可以的,但是如果沒有這個就沒有意義
3:有父類或者父介面引用指向子類物件
Fu f = new Zi();
多型的分類:
1:具體類多型:
class Fu{}
class Zi extends Fu{}
Fu f = new Zi();
2:抽象類多型
abstract class Fu{}
class Zi extends Fu{}
Fu f =new Zi();
3:介面多型
interface Fu{}
class Zi implements Fu{}
Fu f = new Zi();
多型中成員的訪問特點:
1:成員變數
編譯看左邊,即看Fu類中的成員變數
Fu f = new Zi();
執行看左邊
2:構造方法
建立子類物件的時候,訪問父類的構造方法,對父類的資料進行初始化
3:成員方法
編譯看左邊,執行看右邊(方法存在覆蓋)
4:靜態方法
編譯看左邊,執行看右邊(靜態和類相關,算不上重寫,所以訪問還是左邊的)
多型的好處:
1:提高了程式碼的維護性(繼承保證)
2:提高了程式碼的拓展性(由多型保證)
多型的弊端:
不能使用子類的特有功能
怎麼使用:
Fu f = new Zi();
方式1:建立子類物件呼叫方法即可(很多時候不合理,而且佔記憶體)
方式2:Zi z = (Zi)f;
z.show();
z.method()
把父類的的引用強制轉換為子類的引用。(向下轉換)
多型物件間的轉型問題:
向上轉型:
Fu f = New Zi();
向下轉型:
Zi z = (Zi)f; 要求改f必須是能夠轉換為Zi的
抽象類:在java中,一個沒有方法體的方法應該定義為抽象類,如果類中有抽象方法,該類必須定義為抽象類
抽象類的特點:
1:抽象類和抽象方法必須用abstract關鍵字修飾
2:抽象類中不一定有抽象方法,但有抽象方法的類必須定義為抽象類
3:抽象類不能例項化
因為它不是具體的
抽象類有構造方法,但是不能例項化,用於子類訪問父類資料的初始化
4:抽象類的子類
a:如果不想重寫抽象方法,該子類是一個抽象類
b:重寫所有的抽象方法,這個時候子類是一個具體的類
抽象類的例項化其實靠具體的子類實現的。是多型的方式
抽象類的成員特點:
成員變數:既可以是常量,也可以是變數
構造方法:有構造方法,不能例項化
作用:用於子類訪問父類資料的初始化
成員方法:既可以是抽象的,也可以是非抽象的
抽象類的成員方法特性:
1:抽象方法,強制要求子類做的事情
2:非抽象方法,子類繼承的事情,提高程式碼的複用性
abstract不能那些關鍵字共存:
private 衝突
final 衝突
static 無意義
介面:為了體現事物功能的拓展性,java中就提供了介面來定義這些額外功能,並不給出具體實現,將來那些類需要這些功能,只需這些類實現額外功能即可
介面特點:
1:介面用關鍵字interface表示
interface 介面名{}
2:類實現介面用implements表示
class 類名 implements 介面名{}
3:介面不能例項化
那麼,介面如何例項化
按照多型的方式來例項化
由此可見:
1:具體類多型(幾乎沒有)
2:抽象類多型(常用)
3:介面多型(最常用)
4:介面的子類
1:可以是抽象類,但意義不大
2:可以是具體類。要重寫介面中的所有抽象方法。(推薦方案)
介面成員特點:
成員變數:只能是常量,並且是靜態的
預設修飾符:public static final(建議自己手動給出)
構造方法:介面沒有構造方法
成員方法:只能是抽象方法
預設修飾符:public abstract
所有的類都預設繼承自一個類:Object
類與類的關係:繼承關係,只能單繼承,可以多層繼承
類與介面:
實現關係,可以單實現,也可以多實現
並且還可以在繼承一個類的同時實現多個介面
介面與介面:
繼承關係:可以單繼承,也可以多繼承。
抽象類和介面的區別:
1:成員區別
抽象類:
成員變數:可以變數,也可以常量
構造方法:有
成員方法:可以抽象,也可以不抽象
介面:
成員變數:只可以是常量
成員方法:只可以抽象
2:關係區別
類與類:
繼承,單繼承
類與介面:
實現,單實現,多實現
介面與介面:
繼承,單繼承,多繼承
3:設計理念區別
抽象類 被繼承體現的是:"is a"的關係。抽象類中定義的該繼承體系的共性功能。
介面 被實現體現的是:"like a"的關係。介面中定義的是該繼承體系的拓展功能。
形式引數:
基本型別:
引用型別:
類名:(匿名物件時講過)需要的是該類的物件
抽象類名:需要的是該抽象類的子類物件
介面名:需要的是該介面的實現類物件
返回值型別
基本型別:
引用型別:
類:返回的是該類的物件
抽象類:返回的是該抽象類的子類物件
介面:返回的是該介面的實現類物件
鏈式程式設計:每次呼叫完畢方法後,返回的是一個物件
S1 s =new S1();
//S2 s2 = s.getXxx();
//s2.fun();
s.getXxx().fun();
包:其實就是資料夾
作用:
把相同的類名放到不同的包中
對類進行分類管理
按功能分:
按模組分:
包的定義:
packa 包名;多級包用.分開即可
注意事項:
1:package語句必須是程式的第一條可執行的程式碼
2:package語句在一個java檔案中只能有一個
3:如果沒有package,預設表示無包名
帶包的編譯和執行:
1:手動式:
a:編寫一個帶包的java檔案
b:通過javac命令編譯該java檔案
c:手動建立包名
d:把b步驟的class檔案放到c步驟的最底層包
e:回到和包根目錄在同一目錄的地方,然後執行
帶包執行
java cn.itcat.HelloWorld
2:自動式:
a:編寫一個帶包的java檔案
b:javac編譯的時候帶上-d即可
javac -d . HelloWorld.java
c:回到和包根目錄在同一目錄的地方,然後執行
帶包執行
java cn.com.HelloWorld
不同包下類之間的訪問:
導包概述:
不同包之下的類之間訪問,我們發現,每次使用不同包下的類的時候,都需要加包的全路徑,比較麻煩
這個時候。java就提供了導包的功能
導包格式
import 包名;
注意:
這種方式匯入是到類的名字
雖然可以最後可以寫*,但是不建議。
import com.fengzelang.Test;開發中用誰導誰
package>Import>class
package:只能有一個
import:可以有多個
class:可以有多個,以後建議是一個
許可權修飾符:
修飾符 本類 同一個包下(子類和無關類) 不同包下(子類) 不同包下(無關類)
private Y
預設 Y Y
protected Y Y Y
public Y Y Y Y
類及其組成所使用的常見修飾符
許可權修飾符:private,預設的,protected,public
狀態修飾符:static,final
抽象修飾符:abstract
類:
許可權修飾符:預設修飾符,public
狀態修飾符:final
抽象修飾符:abstract
用的最多:public
成員變數:
許可權修飾符:private,預設的,protected,public
狀態修飾符:static,final
用的最多:private
構造方法:
許可權修飾符:private,預設的,protected,public
用的最多:public
成員方法:
許可權修飾符:private,預設的,protected,public
狀態修飾符:static,final
抽象修飾符:abstract
用的最多:public
除此以外的組合規則:
成員變數:public static final
成員方法:public static
public abstract
public final
內部類概述:
把類定義在其他類的內部,這個類就被稱為內部類
內部類的訪問特點:
1:內部類可以訪問外部類的成員,包括私有
2:外部類要訪問內部類的成員,必須建立物件。
內部類的分類:
1:成員內部類
2:區域性內部類
成員內部類
1:private為了資料的安全性
2:static為了訪問 的方便性
成員內部類不是靜態的:
外部類名.內部類名 物件名 = new 外部類名.new 內部類名();
成員內部類是靜態的:
外部類名.內部類名 物件名 = new 外部類類名.內部類名();
靜態內部類訪問的外部類資料必須用靜態修飾
成員內部類被靜態修飾後的訪問方式是:
格式:外部類名.內部類名 物件名 = new 外部類名.內部類名();
注意:
內部類和外部類沒有繼承關係
通過外部類名限定this物件
區域性內部類:
1:可以直接訪問外部類的成員
2:在區域性位置,可以建立內部類的物件,通過物件呼叫內部類方法,來使用區域性內部類功能
區域性內部類訪問區域性變數的注意事項:
1:區域性內部類訪問區域性變數必須用final修飾
因為區域性變數會隨著方法的呼叫完畢而消失,這個時候,區域性物件並沒有立馬從堆記憶體中消失
還要繼續使用哪個變數。為了讓資料還能繼續被使用,就用final。這樣。在堆記憶體中儲存的是常量
匿名內部類:
就是內部類的簡化寫法
前提:存在一個介面或者類
這裡的類可以是具體類也可以是抽象類
格式:
new 類名或者介面(){
重寫方法;
}
本質:
是一個繼承了該類或者實現了該介面的子類匿名物件
interface Inter{
public abstract void show();
}
class Outer{
public void method(){
new Inter(){
public void show(){
System.out.println("show");
}
}.show();//物件呼叫方法
}
}
//多個方法很難呼叫
interface Inter{
public abstract void show();
public abstract void show2();
}
class Outer{
public void method(){
Inter i = new Inter(){//多型
public void show(){
System.out.println("show");
}
public void show2(){
System.out.println("show2");
}
};
i.show();
i.show2();
}
}
匿名內部類在開發中使用: