面向?qū)ο笕筇匦裕?/h1>
- 封裝
- 繼承
- 多態(tài)
1.什么是封裝:
顧名思義郭厌,封:封閉竣蹦,裝:裝起來筝野,將具體的實現(xiàn)細節(jié)裝到一個容器中晌姚,并封閉起來,防止容器外部直接訪問容器內(nèi)部的實現(xiàn)細節(jié)歇竟,僅公開暴露指定的訪問路徑挥唠;生活中的例子:到飯館吃飯,你只需要跟服務(wù)員講你要吃什么飯菜焕议,服務(wù)員就會跟后臺廚房的廚師說明一下宝磨,等待一段時間后,飯菜就被服務(wù)員直接遞送到你面前盅安,作為客戶的你是不知道也無需知道飯菜的具體做法唤锉,后臺廚房的廚師及做飯菜的過程就是被封裝的細節(jié),而服務(wù)員則是公開暴露的訪問路徑别瞭,你只能通過服務(wù)員點餐然后獲得飯菜窿祥,而不能直接去到后臺廚房要求廚師如何做飯菜。
讓我會心一笑蝙寨,封裝的場景一定會在你腦海里飄過一種熟悉感晒衩,js里的閉包就是封裝的一種嗤瞎。
2.繼承
最適合用的就是 寄生組合繼承
何為組合? 其實就是 構(gòu)造函數(shù) + 原型繼承
先說原型繼承吧听系! 其實很簡單就是:
function animal(size){
this.size = size;
}
function cat (){
...
}
var aniIns = new animal('5米')
cat.prototype = aniIns;
catPiPi = new cat()
catPiPi.size // '5米'
很簡單的繼承方式贝奇, size繼承于父。 但是問題是 你創(chuàng)建的所有的貓的size的值都會一樣靠胜。為了改變這個問題引入構(gòu)造函數(shù)模式掉瞳。
function animal(size){
this.size = size;
}
function cat (size){
animal.call(this,arguments)
}
var aniIns = new animal('3米')
cat.prototype = aniIns;
catPiPi = new cat('1米');
catYaoRan = new cat('1.5米');
catPiPi.size // '1米'
catYaoRan.size // '1.5米'
這就是組合方式了,然而其缺點十分明顯浪漠。 兩只貓都有自己的size 同時原型鏈上也有一個size 就是說多了陕习。我們不想要那個size 但是我們想要animal的原型 那么在組合的基礎(chǔ)上 使用寄生模式。
function animal(size){
this.size = size;
}
function constructorPro(){
var func = new Function();
func.prototype = animal.prototype
return func
}
function cat (size){
animal.call(this,arguments)
}
var aniIns = new animal('3米')
cat.prototype = constructorPro();
catPiPi = new cat('1米');
catYaoRan = new cat('1.5米');
catPiPi.size // '1米'
catYaoRan.size // '1.5米'
且原型鏈上沒有cat了郑藏。為了讓他的constructor正常 還要做一件事 就是 constructor賦值下:
function animal(size){
this.size = size;
}
function constructorPro(){
var func = new Function();
func.prototype = animal.prototype
func.prototype.constructor = animal // 這里做了改變衡查,相比較與上面那個。
return func
}
function cat (size){
animal.call(this,arguments)
}
var aniIns = new animal('3米')
cat.prototype = constructorPro();
catPiPi = new cat('1米');
catYaoRan = new cat('1.5米');
catPiPi.size // '1米'
catYaoRan.size // '1.5米'
3.多態(tài):
多態(tài)其實是指在 編譯的過程中無法確定變量的類型或執(zhí)行函數(shù)最終結(jié)果必盖,只有在運行的時候才能確定拌牲。(土話 下面給出好點的描述)(方法和變量都有多態(tài))
所謂多態(tài)就是指程序中定義的引用變量所指向的具體類型或通過該引用變量發(fā)出的方法調(diào)用在編程時并不確定,而是在程序運行期間才確定歌粥,即一個引用變量倒底會指向哪個類的實例對象塌忽,該引用變量發(fā)出的方法調(diào)用到底是哪個類中實現(xiàn)的方法,必須在由程序運行期間才能決定失驶。
在java中土居,最常用的多態(tài)是通過,繼承嬉探、構(gòu)造擦耀、向上轉(zhuǎn)型來實現(xiàn)的。還是拿貓的例子來說吧涩堤。
public class animal{
private float size;
public void animal(Float size) {
size = size;
}
public void jiao (String type){
system.out.println(type);
}
}
public class cat extends animal{
public void cat(String size){
size = size;
}
public void jiao(){
system.out.println('喵喵喵')
}
public void jiao(String prefix, String sufix ){
system.out.println(prefix + '喵喵喵' + sufix)
}
}
Java多態(tài)的分類
1眷蜓、編譯時多態(tài),即方法的重載 ( 多個名字想同的函數(shù) 參數(shù)不同胎围,) 吁系,從JVM的角度來講,這是一種靜態(tài)分派(static dispatch)
2白魂、運行時多態(tài)汽纤,即方法的重寫 ( 運行時父類繼承的方法或變量會被重新,每個對象狀態(tài)都不一樣福荸,從字面意思來看也是一種多態(tài)蕴坪。 ) ,從JVM的角度來講敬锐,這是一種動態(tài)分派(dynamic dispatch)辞嗡。
其實在js中多態(tài)更加簡單:
function animal(size,jiaosheng){
this.size = size;
this.jiaosheng = jiaosheng
this.jiao = function(){
console.log(this.jiaosheng)
}
}
function cat (size,jiaosheng){
animal.call(this,arguments)
}
var aniIns = new animal('3米','lallal')
cat.prototype = aniIns;
catPiPi = new cat('1米','喵喵喵');
catYaoRan = new cat('1.5米'捆等,'喵嗚喵嗚');
catPiPi.jiao() // '喵喵喵'
catYaoRan.jiao() // '喵嗚喵嗚'