- 相關(guān)推薦
Java面向?qū)ο蟮娜筇匦?/p>
Java面向?qū)ο蟮娜筇匦苑謩e為:封裝、繼承、多態(tài),下面我們一起來(lái)詳細(xì)了解一下!
1.封裝:
說(shuō)得通俗一點(diǎn),就是把細(xì)節(jié)隱藏起來(lái),把該公開(kāi)的公開(kāi),把該私有的私有。
那如何封裝一個(gè)類(lèi)?
類(lèi)中含屬性和方法, 屬性可有可無(wú),并且應(yīng)該設(shè)置為private.
方法可有可無(wú),對(duì)外的方法的應(yīng)該公開(kāi),對(duì)內(nèi)的方法應(yīng)該私有.
一個(gè)類(lèi)的方法,大致有:
構(gòu)造方法 -> 可以生成
存/取 屬性值的方法,也就是 getter/setter 屬性方法. -> 可以生成
業(yè)務(wù)方法,實(shí)現(xiàn)此類(lèi)對(duì)象的真正業(yè)務(wù)功能,是程序員真正需要花心思考慮的。
針對(duì)類(lèi)中的方法,有以下兩種封裝策略:
1).把存/取屬性方法、構(gòu)造方法、業(yè)務(wù)方法全部封裝到同個(gè)類(lèi)中。
2).把業(yè)務(wù)方法單獨(dú)獨(dú)立出來(lái),形成一個(gè)業(yè)務(wù)類(lèi),這個(gè)類(lèi)用來(lái)操作與它所相關(guān)的實(shí)體對(duì)象。它一般由接口與實(shí)現(xiàn)類(lèi)組成.
實(shí)體(Entity)對(duì)象,就是指含業(yè)務(wù)屬性和屬性存/取 方法的對(duì)象.
如:封裝策略一:
public class Account {
private long id;
private String name;
private double balance;
private String pwd;
....
// getter/setter方法
// 構(gòu)造方法
....
// 業(yè)務(wù)方法
public void withdraw(double money) {
if(balance < money) {
System.out.println("余額不足");
return ;
}
balance -= money;
}
public void deposit(double money) { }
}
//采用封裝策略二:
首先是實(shí)體類(lèi)
public class Account {
private long id;
private String name;
private double balance;
private String pwd;
....
// getter/setter方法
// 構(gòu)造方法
}
//再定義一個(gè)業(yè)務(wù)類(lèi),操作Account
public class AccountService {
// 業(yè)務(wù)方法
public void withdraw(Account a,double money) {
if(a.getBalance() < money) {
System.out.println("余額不足");
return ;
}
a.setBalance(a.getBalance - money);
}
public void deposit(Account a, double money) { }
}
注:此處在真實(shí)的場(chǎng)景中應(yīng)該由接口與實(shí)現(xiàn)類(lèi)組成。
2.繼承
關(guān)鍵字: extends
類(lèi)繼承的語(yǔ)法:
public class 子類(lèi)名 extends 父類(lèi)名 {
//屬性定義
//方法定義
}
注:一個(gè)類(lèi)A繼承了另一個(gè)類(lèi)B,那么類(lèi)A中就繼承(得到)了類(lèi)B中所有的非私有成員.
繼承的特點(diǎn):
1).傳遞性,如果A繼承B,C又繼承A, 那么C也繼承B。
2).JAVA是單繼承的。
JAVA中有一個(gè)頂級(jí)父類(lèi),就是java.lang.Object 類(lèi)如果一個(gè)類(lèi)沒(méi)有繼承任何父類(lèi),那么它將會(huì)自動(dòng)繼承于Object類(lèi).
單繼承的特點(diǎn),可以保證JAVA的整個(gè)類(lèi)層次結(jié)構(gòu)一顆“倒置樹(shù)”狀結(jié)構(gòu)
如:
//父類(lèi)
public class Super {
private String name;
//
//..
}
// 子類(lèi)
public class Sub extends Super {
//...
}
繼承所產(chǎn)生的幾個(gè)概念:
父類(lèi),也叫超類(lèi),或叫 基類(lèi)。
子類(lèi),也叫派生類(lèi)。
何時(shí)使用繼承?
當(dāng)兩個(gè)類(lèi)之間具備“ IS A "的關(guān)系時(shí),才應(yīng)該采用繼承關(guān)系. 否則,不要濫用繼承.
如:
Apple IS A Fruiut
Cat is a Animal
...
繼承是一種代碼復(fù)用技術(shù),但是提出這個(gè)“IS A”的參考要求是為了更好地“限制”繼承,因?yàn),代碼復(fù)用技術(shù)除了繼承外,還有其它的設(shè)計(jì)思想,比如 組合/聚合設(shè)計(jì)思想.
-- ----------------------------------------------------------
對(duì)象創(chuàng)建的過(guò)程:
a).分配空間
b).賦初始值
c).調(diào)用構(gòu)造方法
如果有了父類(lèi),則應(yīng)該是:
第一步:遞歸地按以上三步創(chuàng)建 父類(lèi)對(duì)象.
## ############################################
創(chuàng)建子類(lèi)對(duì)象時(shí),一定會(huì)遞歸地創(chuàng)建父類(lèi)對(duì)象
## ############################################
super關(guān)鍵字:
作用:
a).在構(gòu)造方法中使用,調(diào)用父類(lèi)構(gòu)造方法,必需放在第一條語(yǔ)句
b).當(dāng)子類(lèi)的屬性與父類(lèi)屬性同名時(shí),并且父類(lèi)的屬性不是private的這種情況下,在子類(lèi)中,存在2個(gè)同名的屬性,那么子類(lèi)的屬性會(huì)掩蓋(shadow)掉父類(lèi)的同名屬性,這時(shí),可以通過(guò)super.屬性名來(lái)區(qū)別。
-- -------------------------------------------------------
有了繼承關(guān)系,父類(lèi)類(lèi)型的引用可以指向任意的子類(lèi)對(duì)象。
編譯時(shí)類(lèi)型
就是指變量在編譯時(shí)的類(lèi)型,也就是申明變量時(shí)它的類(lèi)型
運(yùn)行時(shí)類(lèi)型
就是指代碼運(yùn)行時(shí)變量的真正類(lèi)型,也就是new操作符后面所跟的對(duì)象類(lèi)型.
如:
Animal c2;
c2 = new Cat(); //可以指向 Cat的實(shí)例
Object c3 = new Cat(); //Object類(lèi)型的引用可以指向任意對(duì)象。
c3.catchMouse(); // error, 此處不能調(diào)用此方法。
所以,Object類(lèi)型可以成為任意對(duì)象的編譯時(shí)類(lèi)型.
但是,編譯時(shí)類(lèi)型只能看到編譯時(shí)類(lèi)型所擁有的成員.[這就是為什么c3.catchMouse() 會(huì)報(bào)錯(cuò),因?yàn)閏3的編譯時(shí)類(lèi)型是Object,并沒(méi)有catchMouse()方法]
-- ------------------------------------------------------
共性與個(gè)性
共性盡可能寫(xiě)在父類(lèi)之中,這樣所有子類(lèi)都可以共享.
個(gè)性盡可能寫(xiě)在子類(lèi)之中,每種子類(lèi)都具備不同的個(gè)性.
-- ------------------------------------------------------
instanceof 操作符
作用:用來(lái)判斷一個(gè)對(duì)象是否屬于某個(gè)類(lèi)型
語(yǔ)法:
變量名 instanceof 類(lèi)型
以上表達(dá)式返回的是 boolean類(lèi)型.
當(dāng)instanceof后面的類(lèi)型是變量的運(yùn)行時(shí)類(lèi)型或可以是做為它編譯時(shí)類(lèi)型的類(lèi)型時(shí),返回true.
如:
Animal a = new Dog();
if(a instanceof Dog) { //成立
...
}
if(a instanceof Animal){ //成立
...
}
if(a instanceof Cat){ //不成立
...
}
3.多態(tài).
具備同一種編譯時(shí)類(lèi)型的對(duì)象引用,調(diào)用同一個(gè)方法,而在運(yùn)行時(shí)具備不同的形為. 這就是多態(tài).
多態(tài)的條件
1).要有繼承關(guān)系
2).要有方法重寫(xiě)(override)
方法的組成部份:
修飾符 返回類(lèi)型 方法名([參數(shù)列表]) 拋出異常 { }
方法重寫(xiě)的條件
a).修飾符要一樣,或者子類(lèi)方法的修飾符要比父類(lèi)寬
b).返回類(lèi)型一致,或者子類(lèi)方法的返回類(lèi)型是父類(lèi)方法返回類(lèi)型的子類(lèi)。
c).方法名一樣
d).參數(shù)列表要一模一樣。
e).拋出的異常只能比父類(lèi)要小。
-- ------------------------------------------------------
多態(tài)的應(yīng)用
面向父類(lèi)編程,這是一種編程思想,具體在代碼上可以有如下三種體現(xiàn):
a).對(duì)象的編譯時(shí)類(lèi)型盡可能地寫(xiě) 父類(lèi)類(lèi)型
如:Animal c = new Cat();
b).方法的參數(shù)盡可能寫(xiě)父類(lèi)
試想,如果要寫(xiě)義一個(gè)功能,這個(gè)功能盡可以用小貓做參數(shù),也可以用小狗做參數(shù),則:
public void m(Cat c) { c.eat(); }
public void m(Dog c) { c.eat(); }
即然Cat類(lèi)和Dog類(lèi)有共同的父類(lèi),為什么不考慮如下的方式:
public void m(Animal a) { a.eat(); } //顯然,此方法更好,可以有效地減少方法的重載。
c).方法返回類(lèi)型盡可能地寫(xiě) 父類(lèi).
如:
public Animal createAnimal() { .... } //這樣的好處是這個(gè)方法有更多的可選擇性,也就是并不只是返回一種類(lèi)型。
增強(qiáng)for循環(huán),只能用循環(huán)迭代數(shù)組和集合. 它是JDK5.0后才有的.
語(yǔ)法:
for(類(lèi)型 變量名 : 數(shù)組或集合對(duì)象) {
//代碼
}
注:類(lèi)型 指的是數(shù)組元素的類(lèi)型或集合元素的類(lèi)型.
-- -----------------------------------------------------
toString方法
打印一個(gè)對(duì)象時(shí),會(huì)自動(dòng)調(diào)用該對(duì)象的 toString方法。因?yàn)閠oString()方法是 Object類(lèi)中的方法,所以,每個(gè)對(duì)象都有toString()方法。但是,Object的toString方法的默認(rèn)實(shí)現(xiàn)只是返回對(duì)象的”內(nèi)存地址“,所以,如果你想要輸出你自己定義的對(duì)象字符串格式,請(qǐng) 重寫(xiě) toString方法.
-- --------------------------------------------------------
練習(xí):
設(shè)計(jì)一個(gè)形狀類(lèi)Shape, 沒(méi)有任何的屬性。
含如下方法:
public double area() { return 0.0;}
public double girth() { return 0.0; }
再寫(xiě)一個(gè)子類(lèi):圓形(Circle) 繼承于 形狀類(lèi).自行設(shè)計(jì)屬性,并重寫(xiě)父類(lèi)的 area和girth方法.
靜態(tài)[static]與常量[final]
靜態(tài)域與靜態(tài)方法,關(guān)鍵字:static
1.static用來(lái)修飾屬性(成員變量)
static修飾的屬性叫靜態(tài)屬性,也稱(chēng)為 類(lèi)變量.
語(yǔ)法:
訪問(wèn)控制修飾符 static 變量類(lèi)型 變量名 [=初始值];
我們知道,普通屬性是對(duì)象所擁有的,而類(lèi)變量(靜態(tài)屬性)則是類(lèi)所擁有的,是所有對(duì)象所共享的。
2.static用來(lái)修飾方法(成員方法)
就是在方法的修飾符中加入 static關(guān)鍵字,這個(gè)方法就成為了靜態(tài)方法。
靜態(tài)方法的特點(diǎn):
a).靜態(tài)方法無(wú)需創(chuàng)建對(duì)象來(lái)調(diào)用。直接通過(guò)類(lèi)名.方法名 來(lái)調(diào)用.
b).靜態(tài)方法中不能直接訪問(wèn)非靜態(tài)成員,只能創(chuàng)建對(duì)象來(lái)訪問(wèn)非靜態(tài)成員
c).在靜態(tài)方法中不能使用this關(guān)鍵字.
-- 再次回顧對(duì)象創(chuàng)建的過(guò)程
-- 以下三步,都是在類(lèi)加載時(shí)被調(diào)用,并且只會(huì)被執(zhí)行一次.
a).分配靜態(tài)屬性的空間
b).給靜態(tài)屬性賦初始值
c).如果靜態(tài)代碼塊的話,則調(diào)用靜態(tài)代碼塊.
-- 以下四步,都是在創(chuàng)建對(duì)象時(shí)被調(diào)用,并且每創(chuàng)建一個(gè)對(duì)象就執(zhí)行一次
c).分配非靜態(tài)屬性的空間
d).給非靜態(tài)屬性賦初始值
e).如果有代碼塊的話,先調(diào)用代碼塊
f).調(diào)用構(gòu)造方法
3.static 用來(lái)修飾代碼塊.
注:靜態(tài)代碼塊在類(lèi)加載時(shí)只被執(zhí)行一次。它的這個(gè)特性,我們可以利用靜態(tài)代碼做一些特殊的事情
a).加載本地/遠(yuǎn)程的大文件到內(nèi)存中。
b).獲取數(shù)據(jù)庫(kù)連接池
總之一句話,就是需要費(fèi)時(shí)費(fèi)力,而且需要長(zhǎng)駐內(nèi)存的資源,這種情況,可以考慮采用靜態(tài)代碼塊來(lái)負(fù)頁(yè)加載。
【Java面向?qū)ο蟮娜筇匦浴肯嚓P(guān)文章:
Java面向?qū)ο蠛兔嫦蜻^(guò)程的區(qū)別11-03
java面向?qū)ο缶幊讨v解06-18