1:面向?qū)ο蠛兔嫦蜻^程的區(qū)別:
面向過程:
??優(yōu)點:性能比面向?qū)ο蟾?,因為類調(diào)用時需要實例化,開銷比較大,比較消耗資源;比如單片機、嵌入式開發(fā)、Linux/Unix等一般采用面向過程開發(fā),性能是最重要的因素。
缺點:沒有面向?qū)ο笠拙S護(hù)、易復(fù)用、易擴展
面向?qū)ο螅?/p>
??優(yōu)點:易維護(hù)、易復(fù)用、易擴展,由于面向?qū)ο笥蟹庋b、繼承、多態(tài)性的特性,可以設(shè)計出低耦合的系統(tǒng),使系統(tǒng)更加靈活、更加易于維護(hù)
缺點:性能比面向過程低
面向?qū)ο蟮乃季S方法:(終極目標(biāo):減少重復(fù)代碼)
1:首先確定誰來做,然后確定怎么做
2:首先考慮整體,然后考慮局部
3:首先考慮抽象,然后考慮具體
2:對java的了解:

Java分為三個體系:
JavaSE(J2SE)(Java2 Platform Standard Edition,java平臺標(biāo)準(zhǔn)版)
JavaEE(J2EE)(Java 2 Platform,Enterprise Edition,java平臺企業(yè)版)
JavaME(J2ME)(Java 2 Platform Micro Edition,java平臺微型版)。
Java語言的特點:1,簡單易學(xué);2,面向?qū)ο螅ǚ庋b,繼承,多態(tài));3,平臺無關(guān)性(Java虛擬機實現(xiàn)平臺無關(guān)性);4,可靠性;5,安全性;6,支持多線程(C++語言沒有內(nèi)置的多線程機制,因此必須調(diào)用操作系統(tǒng)的多線程功能來進(jìn)行多線程程序設(shè)計,而Java語言卻提供了多線程支持);7,支持網(wǎng)絡(luò)編程并且很方便(Java語言誕生本身就是為簡化網(wǎng)絡(luò)編程設(shè)計的,因此Java語言不僅支持網(wǎng)絡(luò)編程而且很方便);8,編譯與解釋并存
Java是解釋執(zhí)行?
????這個說法不太準(zhǔn)確。我們開發(fā)的 Java的源代碼,首先通過 Javac編譯成為字節(jié)碼(bytecode),然后,在運行時,通過 Java虛擬機(JVM)內(nèi)嵌的解釋器將字節(jié)碼轉(zhuǎn)換成為最終的機器碼。但是常見的 JVM,比如我們大多數(shù)情況使用的 Oracle JDK提供的 Hospot JVM,都提供了 JIT(Just-In-Time)編譯器,也就是通常所說的動態(tài)編譯器,JIT能夠在運行時將熱點代碼編譯成機器碼,這種情況下部分熱點代碼就屬于編譯執(zhí)行,而不是解釋執(zhí)行了
3:三大基本特性
封裝:
1.定義:隱藏對象的屬性和實現(xiàn)細(xì)節(jié),僅對外公開接口,控制在程序中屬性的讀和修改的訪問級別。
2.封裝的目的是:增強安全性和簡化編程,使用者不必了解具體的實現(xiàn)細(xì)節(jié),而只是要通過外部接口,一特定的訪問權(quán)限來使用類的成員。對于封裝而言,一個對象它所封裝的是自己的屬性和方法,所以它是不需要依賴其他對象就可以完成自己的操作。使用封裝有三大好處:
????????????????1、良好的封裝能夠減少耦合。
????????????????2、類內(nèi)部的結(jié)構(gòu)可以自由修改。
????????????????3、可以對成員進(jìn)行更精確的控制。
????????????????4、隱藏信息,實現(xiàn)細(xì)節(jié)。
3.封裝的基本要求是:把所有的屬性私有化,對每個屬性提供getter和setter方法,如果有一個帶參的構(gòu)造函數(shù)的話,那一定要寫一個不帶參的構(gòu)造函數(shù)。在開發(fā)的時候經(jīng)常要對已經(jīng)編寫的類進(jìn)行測試,所以在有的時候還有重寫toString方法,但這不是必須的。
4:權(quán)限:盡可能小,才能體現(xiàn)封裝性,更好的開發(fā)
public:
default默認(rèn):包級別的訪問,在同一包自由訪問,不同包就無法訪問
protected:擁有和default一樣的功能,但是只能修飾成員函數(shù)和成員變量(不能修飾類),允許子類使用父類的protected的成員函數(shù)成員變量(不同包也可以訪問)
private:只能在當(dāng)前類(聲明它的類)使用
繼承:
1.目的:實現(xiàn)代碼的復(fù)用。
2.介紹:當(dāng)兩個類具有相同的特征(屬性)和行為(方法)時,可以將相同的部分抽取出來放到一個類中作為父類,其它兩個類繼承這個父類。繼承后子類自動擁有了父類的屬性和方法,但特別注意的是,父類的私有屬性和構(gòu)造方法并不能被繼承。另外子類可以寫自己特有的屬性和方法,目的是實現(xiàn)功能的擴展,子類也可以復(fù)寫父類的方法即方法的重寫。
?生成對象的方法: 構(gòu)造函數(shù)
????????????類名 對象名=new 類名()
編譯器自動添加 無參構(gòu)造函數(shù),類名()是構(gòu)造函數(shù)且無參,調(diào)用構(gòu)造函數(shù)用new,如果類中有構(gòu)造函數(shù),則不添加無參構(gòu)造函數(shù),(構(gòu)造函數(shù)不能被繼承),在子類的構(gòu)造函數(shù)中,默認(rèn)下會自動調(diào)用父類的無參構(gòu)造函數(shù)super();
?this的用法:“this是指向?qū)ο蟊旧淼囊粋€指針”
this(參數(shù))調(diào)用本類的構(gòu)造函數(shù) super(參數(shù))調(diào)用父類的構(gòu)造函數(shù)
this.函數(shù)名()調(diào)用本類的成員函數(shù) super.函數(shù)名()調(diào)用父類的成員函數(shù)
生成子類的過程:super和this調(diào)用父類函數(shù),必須在第一句,子類可以繼承父類的成員變量和方法,但是不能繼承構(gòu)造函數(shù),可能會有重復(fù)給成員變量賦初始值的情況,所以java默認(rèn)用super();調(diào)用父類無參構(gòu)造函數(shù),或者可以自己寫構(gòu)造函數(shù)
說明在什么情況下需要用到this:
????????第一、通過this調(diào)用另一個構(gòu)造方法,用發(fā)是this(參數(shù)列表),這個僅僅在類的構(gòu)造方法中,別的地方不能這么用。
????????第二、函數(shù)參數(shù)或者函數(shù)中的局部變量和成員變量同名的情況下,成員變量被屏蔽,此時要訪問成員變量則需要用“this.成員變量名”的方式來引用成員變量。當(dāng)然,在沒有同名的情況下,可以直接用成員變量的名字,而不用this。
????????第三、在函數(shù)中,需要引用該函所屬類的當(dāng)前對象時候,直接用this。
super和this的異同:
???????1)this(參數(shù))調(diào)用本類的構(gòu)造函數(shù) super(參數(shù))調(diào)用父類的構(gòu)造函數(shù)
????????this.函數(shù)名()調(diào)用本類的成員函數(shù) super.函數(shù)名()調(diào)用父類的成員函數(shù)
? ? ? 2)this:它代表當(dāng)前對象名(在程序中易產(chǎn)生二義性之處,應(yīng)使用this來指明當(dāng)前對象;如果函數(shù)的形參與類中的成員數(shù)據(jù)同名,這時需用this來指明成員變量名)
? ? ? 3)調(diào)用super()必須寫在子類構(gòu)造方法的第一行,否則編譯不通過。每個子類構(gòu)造方法的第一條語句,都是隱含地調(diào)用super(),如果父類沒有這種形式的構(gòu)造函數(shù),那么在編譯的時候就會報錯。
? 4)this和super不能同時出現(xiàn)在一個構(gòu)造函數(shù)里面,因為this必然會調(diào)用其它的構(gòu)造函數(shù),其它的構(gòu)造函數(shù)必然也會有super語句的存在,所以在同一個構(gòu)造函數(shù)里面有相同的語句,就失去了語句的意義,編譯器也不會通過。
5)this()和super()都指的是對象,所以,均不可以在static環(huán)境中使用。包括:static變量,static方法,static語句塊。
6)從本質(zhì)上講,this是一個指向本對象的指針,?然而super是一個Java關(guān)鍵字。
例如:Dog dog=new Dog()
棧:對象名(對象的引用) 堆:對象本身
子類不能繼承父類中訪問權(quán)限為private的成員變量和方法。子類可以重寫父類的方法,及命名與父類同名的成員變量。有時候我們需要這樣的需求:我們需要將某些事物盡可能地對這個世界隱藏,但是仍然允許子類的成員來訪問它們。這個時候就需要使用到protected。
多態(tài):
1.概念:相同的事物,調(diào)用其相同的方法,參數(shù)也相同時,但表現(xiàn)的行為卻不同。
2. Java實現(xiàn)多態(tài)有三個必要條件:繼承、重寫、向上轉(zhuǎn)型。
?????????繼承:在多態(tài)中必須存在有繼承關(guān)系的子類和父類。
?????????重寫:子類對父類中某些方法進(jìn)行重新定義,在調(diào)用這些方法時就會調(diào)用子類的方法。
?????????向上轉(zhuǎn)型:在多態(tài)中需要將子類的引用賦給父類對象,只有這樣該引用才能夠具備技能調(diào)用父類的方法和子類的方法。
??????只有滿足了上述三個條件,我們才能夠在同一個繼承結(jié)構(gòu)中使用統(tǒng)一的邏輯實現(xiàn)代碼處理不同的對象,從而達(dá)到執(zhí)行不同的行為。
3.多態(tài)的實現(xiàn)方式:
(1)基于繼承實現(xiàn)的多態(tài)
??????基于繼承的實現(xiàn)機制主要表現(xiàn)在父類和繼承該父類的一個或多個子類對某些方法的重寫,多個子類對同一方法的重寫可以表現(xiàn)出不同的行為。
(2)基于接口實現(xiàn)的多態(tài)
??????繼承是通過重寫父類的同一方法的幾個不同子類來體現(xiàn)的,那么就可就是通過實現(xiàn)接口并覆蓋接口中同一方法的幾不同的類體現(xiàn)的。
??????在接口的多態(tài)中,指向接口的引用必須是指定這實現(xiàn)了該接口的一個類的實例程序,在運行時,根據(jù)對象引用的實際類型來執(zhí)行對應(yīng)的方法。
??????繼承都是單繼承,只能為一組相關(guān)的類提供一致的服務(wù)接口。但是接口可以是多繼承多實現(xiàn),它能夠利用一組相關(guān)或者不相關(guān)的接口進(jìn)行組合與擴充,能夠?qū)ν馓峁┮恢碌姆?wù)接口。所以它相對于繼承來說有更好的靈活性。
4.多態(tài)性主要表現(xiàn)在如下方面:
????(1)方法重載.通常指在同一個類中,相同的方法名對應(yīng)著不同的方法實現(xiàn),但是方法的參數(shù)不同.
????(2)成員覆蓋.通常指在不同類(父類和子類)中,允許有相同的變量名,但是數(shù)據(jù)類型不同;也允許有相同的方法名,但是對應(yīng)的方法實現(xiàn)不同.
????(3)對象的轉(zhuǎn)型:面向?qū)ο蠖鄳B(tài)性的體現(xiàn)
????????Person p=new Student()是向上轉(zhuǎn)型,子類的對象賦值給父類的引用P,學(xué)生是人的子類。等于:Student s=new Student();? Person p=s
????????一個引用能夠調(diào)用哪些成員(函數(shù)和變量),取決于引用的類型,P引用的只能是類Person的成員變量
????????一個引用調(diào)用的方法取決于所指向的對象,P調(diào)用的方法取決于指向的Student的類對象,調(diào)用的是Student的方法
????????????????向下轉(zhuǎn)型:
????????????????????????Person p=new Student();
????????????????????????Student s=(Student)p ;
????????????????錯誤的向下轉(zhuǎn)型:p是個人,但并不是拿到一個人,他就一定是學(xué)生
????????????????????????Person p=new Person();
????????????????????????Student s=(Student)p;
5.多態(tài)的好處:程序的可擴展性及可維護(hù)性增強。
抽象:
1.介紹:在面向?qū)ο蟮母拍钪?,我們知道所有的對象都是通過類來描繪的,但是并不是所有的類都是用來描繪對象的,如果一個類中沒有包含足夠的信息來描繪一個具體的對象,這樣的類就是抽象類。抽象類往往用來表征我們在對問題領(lǐng)域進(jìn)行分析、 設(shè)計中得出的抽象概念,是對一系列看上去不同,但是本質(zhì)上相同的具體概念的抽象,我們不能把它們實例化(拿不出一個具體的東西)所以稱之為抽象。
比如:我們要描述“水果”,它就是一個抽象,它有質(zhì)量、體積等一些共性(水果有質(zhì)量),但又缺乏特性(蘋果、橘子都是水果,它們有自己的特性),我們拿不出唯一一種能代表水果的東西(因為蘋果、橘子都不能代表水果),可用抽象類來描述它,所以抽象類是不能夠?qū)嵗摹.?dāng)我們用某個類來具體描述“蘋果”時,這個類就可以繼承描述“水果”的抽象類,我們都知道“蘋果”是一種“水果”。
2.抽象方法:被abstract修飾的方法是抽象方法,抽象方法沒有方法體。修飾符 abstract 返回值類型 函數(shù)名();抽象方法的修飾符只能用public或者protected或者沒有修飾,不能被final,static,private修飾。
(1)、類即使不包含抽象方法,也可以定義成抽象類。
(2)、類中含有抽象方法的類一定要定義成抽象類。
(3)、抽象類中字段的定義和子類的訪問與一般類沒有變化。
(4)、擴展抽象類有兩種方法,第一種是在子類中定義部分抽象方法或者抽象方法不定義,這樣子類也必須定義成抽象類,第二種是定義全部的抽象方法,這樣子類就可以不定義成抽象的了。
(5)、抽象類不能被實例化,但是可以定義一個抽象類的對象變量,這個變量可以引用非抽象子類的對象。
(6)、抽象類中包含有構(gòu)造方法,也可以顯式書寫構(gòu)造方法,構(gòu)造方法在實例化子類的對象中調(diào)用。
4:接口與抽象類的區(qū)別:
不同點:
1、接口可以多實現(xiàn),而抽象類只能單繼承
2、抽象類可以有非抽象的方法和構(gòu)造方法、變量,但是接口只能有抽象方法,靜態(tài)常量。
3、抽象類和子類具有父子關(guān)系,子類能擁有父類中一些屬性。接口雖然某個類實現(xiàn)一個接口,但是由于接口中的變量都為靜態(tài)常量,不存在繼承關(guān)系。
相同點:
1、無論接口還是抽象類,都無法直接實例化,其自身實例化需要靠實現(xiàn)類或子類來實現(xiàn)。
2、接口和抽象類都必須實現(xiàn)其中的所有方法。
抽象類(abstract class)的定義方式如下:?
public abstract class AbstractClass???????????? //里面至少有一個抽象方法
{
? public int t;? //普通數(shù)據(jù)成員
?public abstract void method1();?? //抽象方法,抽象類的子類在類中必須實現(xiàn)抽象類中的抽象方法
? public abstract void method2();?
? public void method3();?? //非抽象方法
? public int method4();
? publi int method4 (){
????? ……?//抽象類中可以賦予非抽象方法方法的默認(rèn)行為,即方法的具體實現(xiàn)
? }
?????? public void method3(){
????? ……?//抽象類中可以賦予非抽象方法方法的默認(rèn)行為,即方法的具體實現(xiàn)
? }?
}
接口(interface)的定義方式如下:?
public interface Interface
{?
? static final int i;? //接口中不能有普通數(shù)據(jù)成員,只能夠有靜態(tài)的不能被修改的數(shù)據(jù)成員,static表示全局,final表示不可修改,可以不用static final?修飾,會隱式的聲明為static和final
public void method1();? //接口中的方法一定是抽象方法,所以不用abstract修飾
? public void method2();??//接口中不能賦予方法的默認(rèn)行為,即不能有方法的具體實現(xiàn)
}
1、一個接口可以被多個類實現(xiàn),一個類也可以實現(xiàn)多個接口。
2、接口中所有的定義的字段默認(rèn)都是public static final 的屬性,寫和不寫沒有區(qū)別。
3、接口中的方法都是抽象的方法,并且抽象的方法默認(rèn)都是public abstract修飾的,不能用其他的修飾符修飾,可以不寫。
4、接口中沒有構(gòu)造方法
5、接口不是類,尤其不能使用new運算符實例化一個接口。但是可以聲明接口的變量,這個變量可以指向?qū)崿F(xiàn)了此接口的子類。
簡言之抽象類是一種功能不全的類,接口只是一個抽象方法聲明和靜態(tài)不能被修改的數(shù)據(jù)的集合,兩者都不能被實例化。
從某種意義上說,接口是一種特殊形式的抽象類,在java語言中抽象類表示的是一種繼承關(guān)系,一個類只能繼承繼承一個抽象類,而一個類卻可以實現(xiàn)多個接口。在許多情況下,接口確實可以代替抽象類,如果你不需要刻意表達(dá)屬性上的繼承的話。
5:七大基本設(shè)計原則
一、單一職責(zé)原則(Single-Responsibility Principle):
單一職責(zé)的含義是:類的職責(zé)單一,引起類變化的原因單一。解釋一下,這也是靈活的前提,如果我們把類拆分成最小的職能單位,那組合與復(fù)用就簡單的多了,如果一個類做的事情太多,在組合的時候,必然會產(chǎn)生不必要的方法出現(xiàn),這實際上是一種污染。所謂職責(zé),我們可以理解他為功能,就是設(shè)計的這個類功能應(yīng)該只有一個,而不是兩個或更多。也可以理解為引用變化的原因,當(dāng)你發(fā)現(xiàn)有兩個不同的變化會要求我們修改這個類,那么你就要考慮撤分這個類了。SRP優(yōu)點:消除耦合,減小因需求變化引起代碼僵化。
二、開閉原則(Open-Close Principal):
開閉原則的含義是:對擴展開放,對修改關(guān)閉。就是,我們寫完的代碼,不能因為需求變化就修改。我們可以通過新增代碼的方式來解決變化的需求。當(dāng)然,這是一種理想的狀態(tài),在現(xiàn)實中,我們要盡量的縮小這種修改。 再解釋一下這條原則的意義所在,我們采用逆向思維方式來想。如果每次需求變動都去修改原有的代碼,那原有的代碼就存在被修改錯誤的風(fēng)險,當(dāng)然這其中存在有意和無意的修改,都會導(dǎo)致原有正常運行的功能失效的風(fēng)險,這樣很有可能會展開可怕的蝴蝶效應(yīng),使維護(hù)工作劇增。
三、里氏替換原則(Liskov-Substituion Principle):
里氏替換原則的含義是:子類可以在任何地方替換它的父類。也就是說在程序中將基類替換為子類,程序的行為不會發(fā)生任何變化。 Liskov替換原則是關(guān)于繼承機制的設(shè)計原則,違反了Liskov替換原則就必然導(dǎo)致違反開放封閉原則。 Liskov替換原則能夠保證系統(tǒng)具有良好的拓展性,同時實現(xiàn)基于多態(tài)的抽象機制,能夠減少代碼冗余,避免運行期的類型判別。
四、依賴倒置原則(Dependecy-Inversion Principle):
面相對象的初期的程序,被調(diào)用者依賴于調(diào)用者。也就是調(diào)用者決定被調(diào)用者有什么方法,有什么樣的實現(xiàn)方式,這種結(jié)構(gòu)在需求變更的時候,會付出很大的代價,甚至推翻重寫。 依賴倒置原則就是要求調(diào)用者和被調(diào)用者都依賴抽象,這樣兩者沒有直接的關(guān)聯(lián)和接觸,在變動的時候,一方的變動不會影響另一方的變動,面向抽象編程,解耦調(diào)用和被調(diào)用者。 具體而言就是高層模塊不依賴于底層模塊,二者都同依賴于抽象;抽象不依賴于具體,具體依賴于抽象。 我們知道,依賴一定會存在于類與類、模塊與模塊之間。當(dāng)兩個模塊之間存在緊密的耦合關(guān)系時,最好的方法就是分離接口和實現(xiàn):在依賴之間定義一個抽象的接口使得高層模塊調(diào)用接口,而底層模塊實現(xiàn)接口的定義,以此來有效控制耦合關(guān)系,達(dá)到依賴于抽象的設(shè)計目標(biāo)。 依賴于抽象是一個通用的原則,而某些時候依賴于細(xì)節(jié)則是在所難免的,必須權(quán)衡在抽象和具體之間的取舍,方法不是一成不變的。依賴于抽象,就是對接口編程,不要對實現(xiàn)編程。
五、接口隔離原則(Interface-Segregation Principle):
它的含義是盡量使用職能單一的接口,而不使用職能復(fù)雜、全面的接口。很好理解,接口是為了讓子類實現(xiàn)的,如果子類想達(dá)到職能單一,那么接口也必須滿足職能單一。 相反,如果接口融合了多個不相關(guān)的方法,那它的子類就被迫要實現(xiàn)所有方法,盡管有些方法是根本用不到的。這就是接口污染。
六、迪米特法則:
又叫作最少知道原則,迪米特原則要求盡量的封裝,盡量的獨立,盡量的使用低級別的訪問修飾符。就是說一個對象應(yīng)當(dāng)對其他對象有盡可能少的了解,不和陌生人說話。這是封裝特性的典型體現(xiàn)。 一個類如果暴露太多私用的方法和字段,會讓調(diào)用者很茫然。并且會給類造成不必要的判斷代碼。所以,我們使用盡量低的訪問修飾符,讓外界不知道我們的內(nèi)部。這也是面向?qū)ο蟮幕舅悸贰_@是迪米特原則的一個特性,無法了解類更多的私有信息。 迪米特原則要求類之間的直接聯(lián)系盡量的少,兩個類的訪問,通過第三個中介類來實現(xiàn)。
七、組合/聚合復(fù)用原則:
組合/聚合復(fù)用原則的含義是,如果只是達(dá)到代碼復(fù)用的目的,盡量使用組合與聚合,而不是繼承。因為繼承的耦合性更大,組合聚合只是引用其他的類的方法,而不會受引用的類的繼承而改變血統(tǒng)。說白了就是我只用你的方法,但我們并不是同類