日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

面向对象1(super、this)

發(fā)布時(shí)間:2024/10/14 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 面向对象1(super、this) 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

?

1.局部變量和成員變量

2.參數(shù)傳遞

2.1基本數(shù)據(jù)類型作為參數(shù)傳遞

2.2 引用類型作為參數(shù)傳遞

3.面向?qū)ο蟮娜齻€(gè)特征

3.1 封裝

3.2 繼承

成員變量

成員方法

3.3 多態(tài)

前提:

定義格式:

缺點(diǎn)

優(yōu)點(diǎn)

4.this關(guān)鍵字

通過this實(shí)現(xiàn)構(gòu)造方法的相互引用

5.super關(guān)鍵字


1. 局部變量和成員變量

?局部變量成員變量
位置方法中或者{ }中類中
內(nèi)存中的位置棧內(nèi)存的方法中堆內(nèi)存的對象中
生命周期隨著方法的運(yùn)行而出現(xiàn)在棧中;隨著方法的彈棧而消失隨著對象的出現(xiàn)而出現(xiàn)在堆中;隨著對象的消失而從堆中消失
初始化

無默認(rèn)初始值;

需手動(dòng)賦值才可用

可不用初始化

所有默認(rèn)的初始化

2. 參數(shù)傳遞

2.1 基本數(shù)據(jù)類型作為參數(shù)傳遞

class Demo{public static void main(String[] args){int x=4;show(x);System.out.println("x="+x); }public static void show(int x){x=5;} }

運(yùn)行結(jié)果:

分析:

將基本類型變量來那個(gè)x空間中的值復(fù)制了一份傳遞給調(diào)用的方法show();

在show()方法中的x接收到了復(fù)制的值,再對x進(jìn)行操作,只會(huì)影響到show中的x;

當(dāng)show()執(zhí)行完彈棧后,程序又回到main()執(zhí)行;

main()中的x還是原來的值。

2.2 引用類型作為參數(shù)傳遞

public class DemoTest {int x;public static void main(String[] args){DemoTest d=new DemoTest();d.x=5;show(d);System.out.println("x="+d.x); }public static void show(DemoTest d){d.x=5;} }

運(yùn)行結(jié)果:

分析:

將引用變量空間中的內(nèi)存地址(引用)復(fù)制了一份傳遞給了show()的d引用變量;

這時(shí)兩個(gè)引用同時(shí)指向堆中的同一個(gè)對象

當(dāng)執(zhí)行了shou()中的d.x=6時(shí),會(huì)根據(jù)d所持有的引用找到堆中的對象,并將其x屬性的值改為6,show()彈棧。

由于兩個(gè)引用指向同一個(gè)對象,不管那個(gè)引用改變了引用所指向的對象中的值,其他引用再次使用都是改變后的值。

3. 面向?qū)ο蟮娜齻€(gè)特征

3.1 封裝

  • 表現(xiàn):方法就是一個(gè)最基本的封裝體,類也是一個(gè)封裝體,用private修飾的變量也是封裝體;
  • 好處:提高了代碼的復(fù)用性;隱藏了具體實(shí)現(xiàn)細(xì)節(jié),需對外提供可訪問的方式(setter()/getter());提高了安全性

3.2 繼承

通過繼承可以是多種事物之間形成一種關(guān)系體系。

關(guān)鍵字:extends

子類在繼承父類后,會(huì)自動(dòng)擁有的父類的成員

  • 好處:提高了代碼的復(fù)用率,提高軟件開發(fā)率;讓類與類之間出現(xiàn)了關(guān)系提供了多態(tài)的前提

注意:

  • Java中只支持單繼承;
  • 多個(gè)類可以繼承一個(gè)類;
  • Java中可多層繼承;
  • Java中,子類和父類是一種相對的概念。

成員變量

當(dāng)子父類出現(xiàn)同名成員變量時(shí),若子類要訪問父類中的成員變量,需使用關(guān)鍵字super;

  • super表示當(dāng)前對象中包含的父類對象空間的引用。

當(dāng)在程序中通過對象調(diào)用方法時(shí):

  • 會(huì)先在子類中查找有沒有對應(yīng)的方法;
  • 若子類中存在,則執(zhí)行子類中的方法;
  • 若子類中沒有,則執(zhí)行父類中響應(yīng)的方法。

成員方法

override:重寫、覆蓋

  • 子類中出現(xiàn)與父類一模一樣的方法
  • 用@Override標(biāo)注
  • 子類覆蓋父類的方法必須保證權(quán)限大于等于父類權(quán)限
  • 必須一模一樣:方法名、參數(shù)列表
  • 弊端:類和類之間耦合度過高
  • 優(yōu)點(diǎn):提高改嗎重用性,可維護(hù)性,是多態(tài)前提之一

所有的類都直接或間接繼承了Object

overload:重載

  • 在同一個(gè)類中,多個(gè)方法名稱相同,參數(shù)列表(個(gè)數(shù)、數(shù)據(jù)類型)不同。

3.3 多態(tài)

表示當(dāng)同一個(gè)操作作用在不同對象上時(shí),會(huì)有不同的語義,從而會(huì)產(chǎn)生不同的結(jié)果。

最終多態(tài)體現(xiàn)為:父類引用可指向子類對象

前提

  • 必須有子父類關(guān)系或者類實(shí)現(xiàn)接口的關(guān)系
  • 方法的重寫
  • 父類引用指向子類對象

在使用多態(tài)后的父類引用變量調(diào)用方法時(shí),會(huì)調(diào)用子類重寫后的方法。(若多個(gè)子類重寫,則調(diào)用的是各個(gè)子類自己重寫的方法(動(dòng)態(tài)綁定))

表現(xiàn)方式

  • 方法的重載(overload):同一個(gè)類中有多個(gè)同名的方法,但這些方法有著不同的參數(shù)(個(gè)數(shù)、類型、順序),在編譯時(shí)可以確定到底調(diào)用哪一個(gè)方法——編譯時(shí)多態(tài)。重載可看做是一個(gè)類中的方法多態(tài)性。
  • 方法的覆蓋(override):子類可以覆蓋父類的方法,因此同樣的方法在子類和父類中會(huì)有著不同的表現(xiàn)形式。
  • 基類的引用變量不止可以指向基類的實(shí)例對象,還可以指向子類的實(shí)例對象。
  • 接口的引用變量也可以指向其實(shí)現(xiàn)類的實(shí)例對象。
  • 程序運(yùn)行的方法在運(yùn)行期才動(dòng)態(tài)綁定(綁定:將一個(gè)方法調(diào)用和一個(gè)方法主體連接到一起 )。
  • 引用變量所指向的具體實(shí)例對象(內(nèi)存里正在運(yùn)行的那個(gè)對象)的方法,而不是引用變量的類型中定義的方法。
  • 通過這種動(dòng)態(tài)綁定的方法實(shí)現(xiàn)了多態(tài)。
  • 只有在運(yùn)行時(shí)再能確定調(diào)用那個(gè)方法,所以這個(gè)多態(tài)叫做——運(yùn)行時(shí)多態(tài)
  • class Base{public Base() {g();}public void f() {System.out.println("Base f()");}public void g() {System.out.println("Base g()");} }class Derived extends Base{public void f() {System.out.println("Derived f()");}public void g() {System.out.println("Derived g()");} }public class DBTest{public static void main(String[] args) {Base b=new Derived();b.f();b.g(); } }

    運(yùn)行結(jié)果

    Base b=new Derived();會(huì)調(diào)用Base類的構(gòu)造方法。而在Base類的構(gòu)造方法中執(zhí)行了g()。由于多態(tài),此時(shí)會(huì)調(diào)用子類Deriverd的g(),而非Base類的g(),因此會(huì)輸出第一個(gè)Derived g()。

    定義格式

    父類 ?? 變量名 = new ? ? 子類();

    抽象類 ?? 變量名 = new ?? 抽象類子類();

    接口 ?? 變量名 = new ?? 接口實(shí)現(xiàn)類();

    當(dāng)子父類出現(xiàn)同名的成員變量時(shí),多態(tài)調(diào)用該變量時(shí),編譯運(yùn)行看左邊(父類);

    • Dad d=new Son();
    • d.num; ?? 調(diào)用的是父類的成員變量
    • 因?yàn)?span style="color:#3399ea;">Java中成員變量沒有重寫的概念。
    class Base{public int i=1; }class Derived extends Base{public int i=2; }public class DBTest{public static void main(String[] args) {Base b=new Derived();System.out.println(b.i);} }

    運(yùn)行結(jié)果

    1

    當(dāng)子父類出現(xiàn)同名的成員方法時(shí),多態(tài)調(diào)用該方法時(shí),編譯看左邊,運(yùn)行看右邊(子類);

    • 編譯時(shí)會(huì)檢查左邊父類中有無對應(yīng)的成員

    當(dāng)子父類出現(xiàn)同名的靜態(tài)方法時(shí),多態(tài)調(diào)用該方法,編譯運(yùn)行看左邊(父類)(相當(dāng)于類名調(diào)用,所以也是看父類);

    • 都看左邊

    缺點(diǎn)

    無法直接訪問子類的特有成員,需向下轉(zhuǎn)型。

    優(yōu)點(diǎn)

    繼承的優(yōu)點(diǎn)(可維護(hù)性);

    可擴(kuò)展性。

    4. this關(guān)鍵字

    可在成員變量上加上this,來區(qū)別成員變量和局部變量

    class Person{private int age;public int getAge() {return this.age;}public void setAge(int age) {this.age=age;} }public class DemoTest{public static void main(String[] args) {Person p=new Person();p.setAge(30);System.out.println(p.getAge());} }

    運(yùn)行結(jié)果:

    分析:

  • 先執(zhí)行main(),壓棧,執(zhí)行其中的Person p=new Person();
  • 在堆內(nèi)存中開辟空間,并為其分配內(nèi)存地址0x1234,成員變量默認(rèn)初始化(age=0);
  • 執(zhí)行p.setAge(30);
  • 調(diào)用setAge(int age),將30賦值給setAge()中的age變量
  • 執(zhí)行this.age=age,將age變量的值30賦值給成員變量this.age;
  • setAge()執(zhí)行完,彈棧,回到main()執(zhí)行輸出語句System.out.println(),輸出p對象中的age值。
  • 若局部變量名和成員變量名相同,在使用時(shí)采用的是就近原則。

    通過this實(shí)現(xiàn)構(gòu)造方法的相互引用

    this(參數(shù)列表)

    package ObjectOriented;class Person{private int age;private String name;Person(){}Person(String nm){name=nm;}Person(int a,String nm){this(nm);age=a;} }public class DemoTest{public static void main(String[] args) {Person p=new Person(30,"張三");} }

    分析:

  • 先執(zhí)行main(),壓棧,執(zhí)行其中的new Person(30,"張三");
  • 堆內(nèi)存中開辟空間,并未其分類內(nèi)存地址0x33,成員變量默認(rèn)初始化(name=null,age=0);
  • 擁有兩個(gè)參數(shù)的構(gòu)造方法(Person(int,String))壓棧,在這個(gè)構(gòu)造方法中有一個(gè)隱式的this,指向堆中的那個(gè)對象
  • 因?yàn)闃?gòu)造方法是給對象初始化的,那個(gè)對象調(diào)用這個(gè)構(gòu)造方法
  • 由于Person(int,String)中使用了this(nm),構(gòu)造方法Person(String)壓棧,并將“張三”傳給nm。
  • 在Person(String)同樣也有this執(zhí)行0x33.執(zhí)行name=nm,將“張三”賦值給成員name。
  • Person(String)彈棧
  • Person(int,String)將30賦值給成員age,彈棧;
  • Person對象在內(nèi)存中構(gòu)建完成,并將0x33賦值給main()中的p引用變量。
  • 5. super關(guān)鍵字

    子類中的所有構(gòu)造方法的第一行由默認(rèn)的隱式的super();語句;

    • 原因:因?yàn)樽宇惱^承了父類的內(nèi)容,所以創(chuàng)建對象時(shí),必須先要看父類是如何對其內(nèi)容進(jìn)行初始化的

    當(dāng)父類中沒有空參構(gòu)造方法時(shí),子類的構(gòu)造方法必須有顯示的super語句,指定要訪問的父類有參的構(gòu)造方法;

    若第一行用this調(diào)用了本類的其他構(gòu)造方法,則此時(shí)無super();

    • 因?yàn)樗鼈兌荚诘谝恍?#xff0c;初始化動(dòng)作要先執(zhí)行
    • super,this不共存

    父類構(gòu)造方法中也有隱式的super

    • 只要是構(gòu)造方法,第一行默認(rèn)都是super();

    父類的父類是Object,它是所有對象的父類。

    由于有super()調(diào)用父類無參構(gòu)造方法,所以父類的構(gòu)造方法既可以給自己的對象初始化,也可以給子類的對象初始化化

    super(arg);——也可以有參數(shù)。

    如果子類構(gòu)造方法的第一行沒有調(diào)用父類的構(gòu)造方法,則會(huì)默認(rèn)調(diào)用副類的無參構(gòu)造(有的話),也可用super(arg)在子類構(gòu)造方法中的第一行顯式調(diào)用父類的有參構(gòu)造。

    父類的構(gòu)造方法會(huì)先執(zhí)行,因?yàn)橄瘸跏蓟割愔械某蓡T變量,自誒后面可能要用到。

    • 訪問父類的構(gòu)造函數(shù):可以使用 super() 函數(shù)訪問父類的構(gòu)造函數(shù),從而委托父類完成一些初始化的工作。
    • 訪問父類的成員:如果子類重寫了父類的中某個(gè)方法的實(shí)現(xiàn),可以通過使用super 關(guān)鍵字來引用父類的方法實(shí)現(xiàn)。
      ?

    ?

    總結(jié)

    以上是生活随笔為你收集整理的面向对象1(super、this)的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。