面向?qū)ο?

多個(gè)對(duì)象的內(nèi)存圖

/*  
 *   Person類 : 描述了人這類事務(wù)的,不具體描述,抽象描述
 *   描述人應(yīng)該具有什么,但是不詳細(xì)
 *   
 *   屬性: 變量  人的性別和年齡   成員變量
 *   行為: 方法  人吃飯,睡覺(jué)行為 成員方法
 *   
 *   屬性和行為 : 類的成員 (組成類的一員)
 */
public class Person {
    //人的姓名
    String name ;
    //人的年齡
    int age;
    
    //人的吃飯行為方法
    public void eat() {
        System.out.println("人在吃飯" + name +".."+age);
    }
    
    //人的睡覺(jué)行為
    public void sleep() {
        System.out.println("人在睡覺(jué)" + name +".."+age);
    }
}
public static void main(String[] args) {
        Person p1 = new Person();
        Person p2 = new Person();
        
        p1.name = "張三";
        p1.age = 20;
        
        p2.name = "李四";
        p2.age = 22;
        
        p1.eat();
        p1.sleep();
        
        p2.eat();
        p2.sleep();
    }
多個(gè)對(duì)象內(nèi)存圖.jpg

封裝

面向?qū)ο蟮某绦蛟O(shè)計(jì)中(oop),包含三大特征. 我們以后開(kāi)發(fā)程序,必須要體現(xiàn)出面向?qū)ο蟮娜筇卣?沒(méi)有體現(xiàn)出現(xiàn)三大特征,不是在用面向?qū)ο笏枷腴_(kāi)發(fā)程序.

  • 封裝 (encapsulation)
  • 繼承 (extends)
  • 多態(tài) (polymorphic)

封裝概念

  • 封裝的定義 : 隱藏具體的實(shí)現(xiàn)細(xì)節(jié),對(duì)外暴露使用方式.
  • 現(xiàn)實(shí)中的封裝實(shí)例 , 筆記本就是例子, 硬件看不到,有什么不知道. 鍵盤(pán),鼠標(biāo)可以操作

封裝的好處

  • 提升安全性
  • 提高程序的復(fù)用性
  • 提高程序的可擴(kuò)展

封裝的實(shí)現(xiàn)

  • 修飾符,也是權(quán)限修飾符 private (私有的)
    • private成員修飾符,不能寫(xiě)在方法里面
    • 被private修飾的成員,訪問(wèn)權(quán)限是最低的
    • 私有修飾的成員,只能在本類使用,出去定義的類,就無(wú)效
  • private私有的修飾,只是封裝的一種體現(xiàn)形式,不能完全代表封裝

提高公共的訪問(wèn)方式

  • 方法的形式出現(xiàn),定義公共方法,讓外界訪問(wèn)私有修飾的成員
  • 方法:對(duì)類的成員變量,賦值或者是取值操作
    • 賦值方法名 : set開(kāi)頭
    • 取值方法名 : get開(kāi)頭
    /*
     * setAge方法,對(duì)成員變量age賦值
     * 值不一定是什么,方法傳遞參數(shù)
     */
    public void setAge(int a) {
        //a的值判斷
        if(a < 0 || a > 120) {
            //自己定義值
            age = 0;
        }else {
            age = a;
        }
    }
    
    //定義方法.獲取age值
    public int getAge() {
        return age;
    }

標(biāo)準(zhǔn)的Person對(duì)象,私有修飾寫(xiě)法(一)

public class Person {
    
    private String name;
    private int age ;
    
    /*
     * name成員變量的get/set方法
     * set方法是賦值的,方法傳遞參數(shù)
     * get方法是獲取值,無(wú)參數(shù),有返回值
     */
    public void setName(String n) {
        name = n;
    }
    
    public String getName() {
        return name;
    }
    
    /*
     * age成員變量的get/set方法
     * set方法是賦值的,方法傳遞參數(shù)
     * get方法是獲取值,無(wú)參數(shù),有返回值
     */
    public void setAge(int a) {
        age = a;
    }
    
    public int getAge() {
        return age;
    }
}
public static void main(String[] args) {
    //創(chuàng)建Person類對(duì)象,調(diào)用方法get/set ,賦值和取值操作
    Person p = new Person();

    p.setName("張三");
    p.setAge(20);

    System.out.println( p.getAge() );
    System.out.println( p.getName() );

}

方法的變量和類的成員變量同名

方法中的變量 (方法體定義的,和參數(shù)中定義),只屬于這個(gè)方法,不屬于其他的任何成員

方法中沒(méi)有定義的變量,使用變量,找成員位置變量

public class Person {
    private String name;
    private int age = 1;
    
    /*
     *  setAge(int a) 閱讀性, 變量a不好理解
     *  見(jiàn)名知意
     */
    public void setAge(int age) {
        age = age;
    }
    
    public int getAge() {
        return age;
    }
}
    public static void main(String[] args) {
        //創(chuàng)建Person類對(duì)象,調(diào)用方法get/set ,賦值和取值操作
        Person p = new Person();
        p.setAge(20);
        System.out.println( p.getAge());
    }
局部變量和成員變量同名問(wèn)題.jpg

this關(guān)鍵字

this翻譯為這個(gè),這里.

this程序中的含義 : this表示當(dāng)前對(duì)象的引用 (this本質(zhì)上理解為就是一個(gè)對(duì)象)

this理解為 : 哪個(gè)對(duì)象調(diào)用的,this就表示哪個(gè)對(duì)象

  • this用法 : this用于區(qū)分成員變量和局部變量的同名問(wèn)題
    • this.變量名 : 表示類中的成員變量
    • 變量名 : 表示方法的具備變量
public class Person {
    private String name;
    private int age = 1;
    
    /*
     *  setAge(int a) 閱讀性, 變量a不好理解
     *  見(jiàn)名知意
     *  區(qū)分出,哪個(gè)age是方法局部的,哪個(gè)age是類的成員的
     *  this關(guān)鍵字區(qū)分
     */
    public void setAge(int age) {
        this.age = age;
    }
    
    public int getAge() {
        return age;
    }
}
this內(nèi)存圖.jpg

成員變量和局部變量區(qū)別

  • 變量的定義上區(qū)別
    • 局部變量定義在方法內(nèi)部,方法參數(shù)
    • 成員變量定義在方法外部,類的里面
  • 變量的作用域上區(qū)別
    • 局部變量作用在方法內(nèi)部,作用在定義的一對(duì){}里面
    • 成員變量作用于整個(gè)的類中
  • 變量的內(nèi)存位置
    • 局部變量,跟隨的方法,進(jìn)入方法棧
    • 成員變量,跟隨對(duì)象進(jìn)入到堆內(nèi)存
  • 變量的生命周期不同
    • 局部變量,跟隨方法出棧,銷毀,相對(duì)較短
    • 成員變量,跟隨對(duì)象進(jìn)入到堆內(nèi)存,等待JVM進(jìn)行垃圾回收, 相對(duì)較長(zhǎng)
  • 變量的初始化值不同
    • 局部變量,不賦值不能使用,沒(méi)有默認(rèn)值
    • 成員變量,在堆內(nèi)存,具有默認(rèn)值的

標(biāo)準(zhǔn)的Person對(duì)象的寫(xiě)法(二)

/*
 * Person類中,定義姓名和年齡成員
 * 要求類的成員變量,私有的修飾
 * 并提供get / set 使用
 * 
 * 標(biāo)準(zhǔn)的寫(xiě)法,以后就這樣寫(xiě)
 */
public class Person {
    private String name;
    private int age;
    
    /*
     * 成員變量,提供get/set方法
     */
    public void setName(String name) {
        this.name = name;
    }
    
    public String getName() {
        return name;
    }
    
    public void setAge(int age) {
        this.age = age;
    }
    
    public int getAge() {
        return age;
    }
}

public static void main(String[] args) {
    //創(chuàng)建Person類對(duì)象,調(diào)用方法get/set ,賦值和取值操作
    Person p = new Person();
    p.setAge(20);
    System.out.println( p.getAge());

    p.setName("李四");
    System.out.println(p.getName());
}

構(gòu)造方法

構(gòu)造方法,稱為構(gòu)造器 (Constructor). 構(gòu)造方法也是方法,作用是創(chuàng)建對(duì)象的時(shí)候使用,可以為對(duì)象進(jìn)行初始化操作.

構(gòu)造方法定義和作用

  • 權(quán)限修飾符
  • 構(gòu)造方法,沒(méi)有返回值類型, void不能寫(xiě)
  • 構(gòu)造方法的名字,有嚴(yán)格限制,必須和類名一致 (一模一樣)
  • 構(gòu)造方法不需要return語(yǔ)句
  • 作用 : 在創(chuàng)建對(duì)象的時(shí)候使用,其他的情況,和構(gòu)造方法無(wú)關(guān)
    • 構(gòu)造方法的允許, new對(duì)象的時(shí)候才運(yùn)行,只運(yùn)行一次
/*
 * 構(gòu)造方法的定義
 * 
 *   - 權(quán)限修飾符
     - 構(gòu)造方法,沒(méi)有返回值類型, void不能寫(xiě)
     - 構(gòu)造方法的名字,有嚴(yán)格限制,必須和類名一致 (一模一樣)
     - 構(gòu)造方法不需要return語(yǔ)句
 */
public class Person {
    //沒(méi)有參數(shù)構(gòu)造方法
    public  Person() {
        System.out.println("無(wú)參數(shù)構(gòu)造方法");
    }
    
    
    public void eat() {
        System.out.println("人在吃飯");
    }
}

構(gòu)造方法實(shí)現(xiàn)對(duì)象的初始化

什么是對(duì)象的初始化操作 : 在對(duì)象的創(chuàng)建過(guò)程中,在new對(duì)象的時(shí)候,使用構(gòu)造方法,為成員變量賦值,這個(gè)動(dòng)作就稱為對(duì)象的初始化操作!

/*
 * 使用構(gòu)造方法,對(duì)象初始化操作
 * 為類中的成員變量賦值
 */
public class Person {
    
    private String name;
    private int age;
    
    /*
     * 為類中的成員變量賦值
     * 成員變量的值,未知的,傳遞參數(shù)
     * 參數(shù)接收姓名和年齡
     */
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void eat() {
        System.out.println("人在吃飯");
    }
}
public static void main(String[] args) {
    //創(chuàng)建Person類對(duì)象
    //建立對(duì)象,就是在調(diào)用構(gòu)造方法
    //構(gòu)造方法需要傳遞參數(shù)
    Person p = new Person("張三",20);
    System.out.println(p);

    p.eat();

    //調(diào)用方法get獲取,成員變量的值
    System.out.println(p.getName());
    System.out.println(p.getAge());
}

思考問(wèn)題

構(gòu)造方法已經(jīng)完成了,對(duì)象初始化操作中,成員變量賦值了,我們是否還需要set方法賦值 ?

肯定需要,以后修改成員變量的數(shù)據(jù),使用set方法來(lái)實(shí)現(xiàn)

構(gòu)造方法的內(nèi)存

構(gòu)造方法也是方法,運(yùn)行必須進(jìn)入棧內(nèi)存

構(gòu)造方法的調(diào)用者是創(chuàng)建的對(duì)象 (創(chuàng)建對(duì)象,稱為實(shí)例化對(duì)象), 對(duì)象會(huì)將地址,傳遞到構(gòu)造方法的this關(guān)鍵字

構(gòu)造方法內(nèi)存圖1.jpg

對(duì)象的半初始化

對(duì)象進(jìn)入內(nèi)存,成員變量賦值,默認(rèn)值,到達(dá)這個(gè)步驟,稱為對(duì)象的半初始化狀態(tài)!

對(duì)象的創(chuàng)建順序 :

  • 對(duì)象先在堆內(nèi)存中,劃分空間 (內(nèi)存地址有了)

  • 初始化成員變量,賦值默認(rèn)值,賦值定義的值

  • 對(duì)象調(diào)用構(gòu)造方法,為成員變量賦值

  • 對(duì)象才會(huì)將地址,賦值到引用變量p

構(gòu)造方法內(nèi)存圖2.jpg

默認(rèn)構(gòu)造方法

對(duì)于任何的一個(gè)類,都必須具有構(gòu)造方法.

  1. 默認(rèn)構(gòu)造方法
    • 在一個(gè)類中,如果我們不去定義構(gòu)造方法,產(chǎn)生一個(gè)默認(rèn)的構(gòu)造方法,是有編譯器javac添加的
    • 默認(rèn)構(gòu)造方法 : 無(wú)參數(shù)的構(gòu)造方法 public 構(gòu)造方法名(){}
    • 如果我們自己手寫(xiě)了構(gòu)造方法,默認(rèn)的就沒(méi)有了
  2. 顯示定義構(gòu)造方法
    • 我們自己的寫(xiě)的構(gòu)造方法,稱為顯示定義,無(wú)論構(gòu)造方法是怎么寫(xiě)的,默認(rèn)的就沒(méi)有了

構(gòu)造方法的重載

構(gòu)造方法也有重載特性 : 同一個(gè)類中,允許定義多個(gè)同名的方法,參數(shù)列表不同,就是重載.

構(gòu)造方法同樣可以定義多個(gè),只要他們之間重載即可

/*
 *  構(gòu)造方法的重載特性
 */
public class Person {
    
    private String name ;
    private int age;
    
    /*
     * 帶有String和int類型的構(gòu)造方法
     */
    public Person(String name , int age) {
        this.name = name;
        this.age = age;
        System.out.println("有參數(shù)的構(gòu)造方法String和int");
    }
    
    //再次定義構(gòu)造方法,必須是重載形式的,無(wú)參數(shù)
    public Person() {
        System.out.println("無(wú)參數(shù)的構(gòu)造方法");
    }
    
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public void eat() {
        System.out.println("人在吃飯");
    }
}
public static void main(String[] args) {
    //創(chuàng)建Person對(duì)象,使用無(wú)參數(shù)構(gòu)造方法
    Person p = new Person();

    p.setName("張三");
    p.setAge(20);
    System.out.println(p.getName());
    System.out.println(p.getAge());

    //創(chuàng)建Person對(duì)象,調(diào)用有參數(shù)的構(gòu)造方法
    Person p2 = new Person("李四",22);
    System.out.println(p2.getName());
    System.out.println(p2.getAge());
}

this語(yǔ)句

this的另一種用法 :

  • this.成員變量,區(qū)分成員變量和局部變量同名
  • 語(yǔ)句用法 this()
  • this語(yǔ)句的使用
    • this() 只能寫(xiě)在構(gòu)造方法的有效代碼第一行
    • this() 語(yǔ)句用來(lái)在構(gòu)造方法中,去調(diào)用另一個(gè)構(gòu)造方法
    • this語(yǔ)句調(diào)用哪個(gè)構(gòu)造方法,看(傳遞的哪些參數(shù))
    public Person(String name , int age) {
        //調(diào)用無(wú)參數(shù)的構(gòu)造方法
        this();
        this.name = name;
        this.age = age;
        System.out.println("有參數(shù)的構(gòu)造方法String和int");
    }   
    public Person() {
        //調(diào)用有參數(shù)的構(gòu)造方法
        //this();
        System.out.println("無(wú)參數(shù)的構(gòu)造方法");
    }

繼承

繼承,英語(yǔ)(extends) 擴(kuò)展; 延伸

通過(guò)一個(gè)例子,引出概念

學(xué)生和老師案例出現(xiàn)了重復(fù)的程序, 共性進(jìn)行了抽取,放在了另一個(gè)類中(Person類).只要學(xué)生類,老師類和Person類產(chǎn)生了某些關(guān)系,就直接可以使用Person類的內(nèi)容了

產(chǎn)生出了父子關(guān)系, 在程序中稱為繼承關(guān)系

繼承 : 類和類之間產(chǎn)生的關(guān)系,繼承關(guān)系. 包含了父和子.

生活中的繼承和程序中繼承關(guān)系

生活中的繼承.jpg

實(shí)現(xiàn)繼承

繼承的關(guān)鍵字 extends, 一個(gè)類繼承另一個(gè)類,使用該關(guān)鍵字

繼承的定義格式 :

public class A(子類) extends B(父類){
}

術(shù)語(yǔ) :

  • A類,繼承B類, A稱為B的子類,又稱為派生類
  • B類,稱為A的父類,又稱為超類,基類

繼承后 : 子類可以直接使用他父類的成員,不是全部

/*
 *  父類  : 定義類,子類共有的內(nèi)容
 *  成員變量,私有修飾
 *  外面的類都不能使用了,包含子類
 *  提供get / set
 */
public class Person {
    private String name;
    private int age;
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}

public class Student extends Person{

}

public class Teacher extends Person{

}
public static void main(String[] args) {
    Student stu = new Student();
    //stu對(duì)象,是Person的子類的對(duì)象
    //子類的對(duì)象,調(diào)用父類的成員
    stu.setName("張三"); //父類繼承的
    stu.setAge(20);

    System.out.println(stu.getName());  //父類繼承的
    System.out.println(stu.getAge());

    Teacher tea = new Teacher();
    //tea對(duì)象,是Person的子類的對(duì)象
    tea.setName("李四");
    tea.setAge(50);

    System.out.println(tea.getName());
    System.out.println(tea.getAge());
}

繼承的好處

  • 繼承是共性的抽取
  • 繼承有效的減少代碼量
  • 提高程序的復(fù)用性和擴(kuò)展性
  • 面向?qū)ο蟮牡谌筇卣鞫鄳B(tài), 多態(tài)的實(shí)現(xiàn)前提就是繼承

繼承的弊端

  • 繼承后,類和類之間的耦合性增強(qiáng) (緊密連接性)
  • 一個(gè)類繼承另一個(gè)類后,不能再繼承其他類了 (單繼承弊端)

Java中的單繼承

  • Java語(yǔ)言只支持單繼承,不支持多繼承
    • 一個(gè)類只能同時(shí)繼承另一個(gè)類
  • Java語(yǔ)言支持多層繼承,稱為多重繼承
繼承的特點(diǎn).jpg

繼承體系

繼承體系圖.jpg
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末膝藕,一起剝皮案震驚了整個(gè)濱河市趋翻,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,718評(píng)論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異轨蛤,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)虫埂,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,683評(píng)論 3 385
  • 文/潘曉璐 我一進(jìn)店門(mén)祥山,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人掉伏,你說(shuō)我怎么就攤上這事缝呕。” “怎么了斧散?”我有些...
    開(kāi)封第一講書(shū)人閱讀 158,207評(píng)論 0 348
  • 文/不壞的土叔 我叫張陵供常,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我鸡捐,道長(zhǎng)栈暇,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,755評(píng)論 1 284
  • 正文 為了忘掉前任箍镜,我火速辦了婚禮源祈,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘色迂。我一直安慰自己香缺,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,862評(píng)論 6 386
  • 文/花漫 我一把揭開(kāi)白布歇僧。 她就那樣靜靜地躺著赫悄,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上埂淮,一...
    開(kāi)封第一講書(shū)人閱讀 50,050評(píng)論 1 291
  • 那天姑隅,我揣著相機(jī)與錄音,去河邊找鬼倔撞。 笑死讲仰,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的痪蝇。 我是一名探鬼主播鄙陡,決...
    沈念sama閱讀 39,136評(píng)論 3 410
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼躏啰!你這毒婦竟也來(lái)了趁矾?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,882評(píng)論 0 268
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤给僵,失蹤者是張志新(化名)和其女友劉穎毫捣,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體帝际,經(jīng)...
    沈念sama閱讀 44,330評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蔓同,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,651評(píng)論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蹲诀。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片斑粱。...
    茶點(diǎn)故事閱讀 38,789評(píng)論 1 341
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖脯爪,靈堂內(nèi)的尸體忽然破棺而出则北,到底是詐尸還是另有隱情,我是刑警寧澤痕慢,帶...
    沈念sama閱讀 34,477評(píng)論 4 333
  • 正文 年R本政府宣布咒锻,位于F島的核電站,受9級(jí)特大地震影響守屉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜蒿辙,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 40,135評(píng)論 3 317
  • 文/蒙蒙 一拇泛、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧思灌,春花似錦俺叭、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,864評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至,卻和暖如春裕照,著一層夾襖步出監(jiān)牢的瞬間攒发,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 32,099評(píng)論 1 267
  • 我被黑心中介騙來(lái)泰國(guó)打工晋南, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惠猿,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,598評(píng)論 2 362
  • 正文 我出身青樓负间,卻偏偏與公主長(zhǎng)得像偶妖,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子政溃,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,697評(píng)論 2 351