(JavaSE基礎(chǔ))一、Java面向?qū)ο?/h2>

1.面向?qū)ο蟮闹饕匦裕ǚ庋b、繼承、多態(tài)、抽象)

  • 封裝
    通常認(rèn)為封裝是把數(shù)據(jù)和操作數(shù)據(jù)的方法綁定起來,對(duì)數(shù)據(jù)的訪問只能通過已定義的接口。面向?qū)ο?br> 的本質(zhì)就是將現(xiàn)實(shí)世界描繪成一系列完全自治、封閉的對(duì)象。我們?cè)陬愔芯帉懙姆椒ň褪菍?duì)實(shí)現(xiàn)細(xì)節(jié)的一種封裝;我們編寫一個(gè)類就是對(duì)數(shù)據(jù)和數(shù)據(jù)操作的封裝??梢哉f,封裝就是隱藏一切可隱藏的東西,只向外界提供最簡(jiǎn)單的編程
    接口。
  • 繼承
    繼承是從已有類得到繼承信息創(chuàng)建新類的過程。提供繼承信息的類被稱為父類(超類、基類);得到繼承信息的類被稱為子類(派生類)。繼承讓變化中的軟件系統(tǒng)有了一定的延續(xù)性,同時(shí)繼承也是封裝程序中可變因素的
    重要手段。
  • 多態(tài)
    多態(tài)性是指允許不同子類型的對(duì)象對(duì)同一消息作出不同的響應(yīng)。簡(jiǎn)單的說就是用同樣的對(duì)象引用調(diào)用同樣的方法但是做了不同的事情。
    多態(tài)性分為編譯時(shí)的多態(tài)性和運(yùn)行時(shí)的多態(tài)性。如果將對(duì)象的方法視為對(duì)象向外界提供的服務(wù),那么運(yùn)行時(shí)的多態(tài)性可以解釋為:當(dāng) A 系統(tǒng)訪問 B 系統(tǒng)提供的服務(wù)時(shí),B 系統(tǒng)有多種提供服務(wù)的方式,但一切對(duì) A 系統(tǒng)來說都是透明的。方法重載(overload)實(shí)現(xiàn)的是編譯時(shí)的多態(tài)性(也稱為前綁定),而方法重寫(override)實(shí)現(xiàn)的是運(yùn)行時(shí)的多態(tài)性(也稱為后綁定)。
    運(yùn)行時(shí)的多態(tài)是面向?qū)ο笞罹璧臇|西,要實(shí)現(xiàn)多態(tài)需要做兩件事:
  1. 方法重寫(子類繼承父類并重寫父類中已有的或抽象的方法);
  2. 對(duì)象造型(用父類型引用引用子類型對(duì)象,這樣同樣的引用調(diào)用同樣的方法就會(huì)根據(jù)子類對(duì)象的不同而表現(xiàn)出不同的行為)。
  • 抽象
    抽象是將一類對(duì)象的共同特征總結(jié)出來構(gòu)造類的過程,包括數(shù)據(jù)抽象和行為抽象兩方面。抽象只關(guān)注對(duì)
    象有哪些屬性和行為,并不關(guān)注這些行為的細(xì)節(jié)是什么。

注意:默認(rèn)情況下面向?qū)ο笥?3 大特性,封裝、繼承、多態(tài),如果面試官問讓說出 4 大特性,那么我們就把抽象加上去。

2.訪問權(quán)限修飾符public、protected、default(不寫時(shí)默認(rèn))、private時(shí)的區(qū)別

image.png

3.如何理解 clone 對(duì)象

3.1 為什么要用 clone?

在實(shí)際編程過程中,我們常常要遇到這種情況:有一個(gè)對(duì)象 A,在某一時(shí)刻 A 中已經(jīng)包含了一些有效值,此時(shí)可能會(huì)需要一個(gè)和 A 完全相同新對(duì)象 B,并且此后對(duì) B 任何改動(dòng)都不會(huì)影響到 A 中的值,也就是說,A 與 B 是兩個(gè)獨(dú)立的對(duì)象,但 B 的初始值是由 A 對(duì)象確定的。在 Java 語言中,用簡(jiǎn)單的賦值語句是不能滿足這種需求的。要滿足這種需求雖然有很多途徑,但實(shí)現(xiàn) clone()方法是其中最簡(jiǎn)單,也是最高效的手段。

3.2 new 一個(gè)對(duì)象的過程和 clone 一個(gè)對(duì)象的過程區(qū)別

new 操作符的本意是分配內(nèi)存。程序執(zhí)行到 new 操作符時(shí),首先去看 new 操作符后面的類型,因?yàn)橹懒祟愋?,才能知道要分配多大的?nèi)存空間。分配完內(nèi)存之后,再調(diào)用構(gòu)造函數(shù),填充對(duì)象的各個(gè)域,這一步叫做對(duì)象的初始化,構(gòu)造方法返回后,一個(gè)對(duì)象創(chuàng)建完畢,可以把他的引用(地址)發(fā)布到外部,在外部就可以使用這個(gè)引用操縱這個(gè)對(duì)象。

clone 在第一步是和 new 相似的,都是分配內(nèi)存,調(diào)用 clone 方法時(shí),分配的內(nèi)存和原對(duì)象(即調(diào)用 clone 方法的對(duì)象)相同,然后再使用原對(duì)象中對(duì)應(yīng)的各個(gè)域,填充新對(duì)象的域,填充完成之后,clone 方法返回,一個(gè)新的相同的對(duì)象被創(chuàng)建,同樣可以把這個(gè)新對(duì)象的引用發(fā)布到外部。

3.3 clone 對(duì)象的使用
3.3.1 復(fù)制對(duì)象和復(fù)制引用的區(qū)別
1. Person p = new Person(23, "zhang");
2. Person p1 = p;
3. System.out.println(p);
4. System.out.println(p1);

當(dāng) Person p1 = p;執(zhí)行之后, 是創(chuàng)建了一個(gè)新的對(duì)象嗎? 首先看打印結(jié)果:

1.com.itheima.Person@2f9ee1ac
2.com.itheima.Person@2f9ee1ac

可以看出,打印的地址值是相同的,既然地址都是相同的,那么肯定是同一個(gè)對(duì)象。p 和 p1 只是引用而已,他們都指向了一個(gè)相同的對(duì)象 Person(23, “zhang”) 。 可以把這種現(xiàn)象叫做引用的復(fù)制。上面代碼執(zhí)行完成之后, 內(nèi)存中的情景如下圖所示:


image.png

而下面的代碼是真真正正的克隆了一個(gè)對(duì)象。

1.Person p = new Person(23, "zhang");
2.Person p1 = (Person) p.clone();
3.System.out.println(p);
4.System.out.println(p1);

從打印結(jié)果可以看出,兩個(gè)對(duì)象的地址是不同的,也就是說創(chuàng)建了新的對(duì)象, 而不是把原對(duì)象的地址賦給了一個(gè)新的引用變量:

1. com.itheima.Person@2f9ee1ac
2. com.itheima.Person@67f1fba0

以上代碼執(zhí)行完成后, 內(nèi)存中的情景如下圖所示:


image.png
3.3.2 深拷貝和淺拷貝

上面的示例代碼中,Person 中有兩個(gè)成員變量,分別是 name 和 age, name 是 String 類型, age 是 int 類
型。代碼非常簡(jiǎn)單,如下所示:

1.public class Person implements Cloneable{
2. privatint age ;
3. private String name;
4. public Person(int age, String name) {
5. this.age = age;
6. this.name = name;
7. }
8. public Person() {}
9. public int getAge() {
10. return age;
11. }
12. public String getName() {
13. return name;
14. }
15. @Override
16. protected Object clone() throws CloneNotSupportedException {
17. return (Person)super.clone();
18. }
19.}

由于 age 是基本數(shù)據(jù)類型,那么對(duì)它的拷貝沒有什么疑議,直接將一個(gè) 4 字節(jié)的整數(shù)值拷貝過來就行。但是 name是 String 類型的, 它只是一個(gè)引用, 指向一個(gè)真正的 String 對(duì)象,那么對(duì)它的拷貝有兩種方式: 直接將原對(duì)象中的 name 的引用值拷貝給新對(duì)象的 name 字段, 或者是根據(jù)原 Person 對(duì)象中的 name 指向的字符串對(duì)象創(chuàng)建一個(gè)新的相同的字符串對(duì)象,將這個(gè)新字符串對(duì)象的引用賦給新拷貝的 Person 對(duì)象的 name 字段。這兩種拷貝方式分別叫做淺拷貝和深拷貝。深拷貝和淺拷貝的原理如下圖所示:


image.png

下面通過代碼進(jìn)行驗(yàn)證。如果兩個(gè) Person 對(duì)象的 name 的地址值相同, 說明兩個(gè)對(duì)象的 name 都指向同一個(gè)String 對(duì)象,也就是淺拷貝, 而如果兩個(gè)對(duì)象的 name 的地址值不同, 那么就說明指向不同的 String 對(duì)象, 也就是在拷貝 Person 對(duì)象的時(shí)候, 同時(shí)拷貝了 name 引用的 String 對(duì)象, 也就是深拷貝。驗(yàn)證代碼如下:

1. Person p = new Person(23, "zhang");
2. Person p1 = (Person) p.clone();
3. String result = p.getName() == p1.getName()
4. ? "clone 是淺拷貝的" : "clone 是深拷貝的";
5. System.out.println(result);

打印結(jié)果為:

6. clone 是淺拷貝的

所以,clone 方法執(zhí)行的是淺拷貝, 在編寫程序時(shí)要注意這個(gè)細(xì)節(jié)。

如何進(jìn)行深拷貝:
由上一節(jié)的內(nèi)容可以得出如下結(jié)論:如果想要深拷貝一個(gè)對(duì)象,這個(gè)對(duì)象必須要實(shí)現(xiàn) Cloneable 接口,實(shí)現(xiàn) clone方法,并且在 clone 方法內(nèi)部,把該對(duì)象引用的其他對(duì)象也要 clone 一份,這就要求這個(gè)被引用的對(duì)象必須也要實(shí)現(xiàn)Cloneable 接口并且實(shí)現(xiàn) clone 方法。那么,按照上面的結(jié)論,實(shí)現(xiàn)以下代碼 Body 類組合了 Head 類,要想深拷貝Body 類,必須在 Body 類的 clone 方法中將 Head 類也要拷貝一份。代碼如下:

1.static class Body implements Cloneable{
2. public Head head;
3. public Body() {}
4. public Body(Head head) {this.head = head;}
5. @Override
6. protected Object clone() throws CloneNotSupportedException {
7. Body newBody = (Body) super.clone();
8. newBody.head = (Head) head.clone();
9. return newBody;
10. }
11.}
12.static class Head implements Cloneable{
13. public Face face;
14. public Head() {}
15. @Override
16. protected Object clone() throws CloneNotSupportedException {
17. return super.clone();
18. } }
19.public static void main(String[] args) throws CloneNotSupportedException {
20. Body body = new Body(new Head(new Face()));
21. Body body1 = (Body) body.clone();
22. System.out.println("body == body1 : " + (body == body1) );
23. System.out.println("body.head == body1.head : " + (body.head == body1.head));
24.}

打印結(jié)果為:

1. body == body1 : false
2. body.head == body1.head : false
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。
禁止轉(zhuǎn)載,如需轉(zhuǎn)載請(qǐng)通過簡(jiǎn)信或評(píng)論聯(lián)系作者。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容