1. 程式人生 > >面向物件、類和物件、封裝---------私有private、this關鍵字

面向物件、類和物件、封裝---------私有private、this關鍵字

1、面向物件和麵向過程

面向物件是讓誰幹什麼

面向過程是按什麼順序來幹(幹活過程都有參與)

所以在工作中,面向物件更好。

例如:

以打掃辦公室為例:面向過程就是將掃地、拖地、擦玻璃、擦門窗這幾件事情排好(做好)順序,先幹啥再幹啥,需要按照順序一件一件的參與幹活‘

面向物件就是打掃衛生時,小李拖地,小楊擦玻璃,小張擦門窗,小孫擦門窗,每個人幹不同的活,最後將辦公室打掃乾淨;

再比如:買電腦:面向過程就是查詢想要的型號,詢價零件、購買、組裝、搬回家。在整個過程中我們參與了每一個細節,並且會感覺相當累。

面向物件就是找個專門懂得人幫忙檢視配置、組裝等,不需要親歷親為具體怎麼做,只要告訴這個人我們想要的具體需求即可。

 面向過程思維方式中更多的體現的是執行者(自己做事情),面向物件中更多的體現是指揮者(指揮物件做事情)。

2、類和物件

 (1)類在需求中的使用--------------類的定義方式及在程式碼中的實現

已將大象關進冰箱這個需求來舉例:

需求:把大象裝冰箱裡

物件:大象、冰箱

分三步:

  第一步開啟冰箱門

  第二部將大象裝進去

  第三步關閉冰箱門

冰箱物件具備如下功能:

  冰箱開啟

  冰箱儲存

  冰箱關閉

------------1、建立冰箱的物件

  冰箱 bx = new 冰箱();  

-----------2、呼叫冰箱的功能

  物件.功能()

  bx.開啟();

  bx.儲存

(new 大象());

  bx.關閉();

程式碼就是:

public class Daxiang {

}//先定義一個Daxiang類
public class Bingxiang {//再定義一個 Bingxiang,類名大寫public void open(){//方法
 System.out.println("冰箱打開了"); } public void save(Daxiang dx){ System.out.println("將大象裝進來"); } public void close(){   System.out.println("冰箱關閉了");   } }
public
class Test {//定義一個測試的類 public static void main(String[] args) { Bingxiang bx = new Bingxiang();//建立物件,new 一個物件 Daxiang dx = new Daxiang(); bx.open();//呼叫方法 bx.save(dx); bx.close(); } }

l定義類的格式

public class 類名 {

  //可編寫0n個屬性

      資料型別 變數名1

      資料型別 變數名2

  //可編寫0n個方法

  修飾符 返回值型別 方法名(引數){

  執行語句;

  }

  }

再以汽車為例:

汽車(事物)的特點(屬性):

汽車的顏色。

輪胎個數。

事物的(功能)

執行。

-----------即:

--------------小汽車 {

------------------------------顏色;

------------------------------輪胎個數;

---------------------執行() { }

---------------------}

public class Car {
    String color;//顏色
    int number;--------------成員變數
    public void run() {//定義一個方法,
        System.out.println(color + ":" + number);
    }
}

類的真正意義就是在描述事物。屬性和功能統稱為事物中的成員。

事物的成員分為兩種:成員屬性和成員功能。

成員屬性在程式碼中的體現就是成員變數

成員功能在程式碼中的體現就是成員方法

public class CarDemo {
    public static void main(String[] args) { 
        /*
         *  測試:Car類中的run方法。
         */
        // 1,建立Car的物件。給物件起個名字。
        Car c = new Car();// c是類型別的變數。c指向了一個具體的Car型別的物件。
        // 2,通過已有的物件呼叫該物件的功能。格式:物件.物件成員;
        // 3,可以該物件的屬性賦值。
        c.color = "red";
        c.number = 4;
        c.run();
    }
}

(2)類和物件的區別

----------------類是對某一類事物的抽象描述,而物件用於表示現實中該類事物的個體。

例如:製作玩具的模型就是類,物件則是一個個玩具

(3)區域性變數和成員變數的區別

第一個:定義位置不同:成員變數是在類中,區域性變數是在方法中或者{}語句裡面

第二個:在記憶體中的位置不同:區域性變數在棧中的方法裡,成員變數在堆中的類中

第三個:生命週期不同:區域性變數隨著方法的執行而出現在棧中,隨著方法的彈棧而消失;成員變數則是隨著類在儲存在堆中,物件消失,成員變數才消失

第四個:初始化不同:成員變數隨著類進入堆中,會被預設賦值為0或者null等,區域性變數沒有初始化值,手動賦值才行

 3、封裝

1、封裝概述

封裝:在方法中,就是將具體的功能封裝到方法中。在物件中就是將方法封裝到類中。

面向物件的三個基本特徵:封裝、繼承、多型

①封裝的表現:

-------------方法就是一個最基本的封裝體

-------------類其實也是一個封裝體

②封裝的好處:

---------------提高了程式碼的複用性

--------------隱藏了實現細節,向外部提供訪問的方式,便於呼叫者使用,這是封裝的核心,也可以說是封裝的概念。

---------------提高了安全性

封裝的舉例說明:就拿桌上型電腦的主機來說,主機有cpu、硬碟、主機板等構成,如果主機外部不加一個外殼,那麼內部的組成部分就裸露在外部,會變得很不安全

外殼就可以看成是一個封裝,其上的USB等介面可以看成是其提供的讓外部訪問的方式。

(2)私有private

類中的屬性的行為可以任意訪問和使用,因此要使用關鍵字也是一個修飾符(私有private)。

例如:

package demo01;
//privat:私有,可以修飾類,被修飾的成員只能在本類中訪問
public class Person {
 private int age;---------------私有化
private String name;
//對外提供公共訪問方式
public void setage(int a){
    if(a>=0&&a<130){
        age=a;
    }else {
    age=0;
    }
}
public int getage(){//-----------------------滑鼠右擊------------Source------Generate Getters and Setter
    return age;
}
public void setname(String n){
    name=n;
}
public String getname(){
    return name;
}
public void speak(){
    System.out.println("我叫"+name+",今年"+age+"歲");
}
} 
package demo01;

public class Text {

    public static void main(String[] args) {
        Person p=new Person();
        p.setname("佩奇");//-------------通過方法賦值。訪問私有的物件屬性
        p.setage(18);
        p.speak();
        System.out.println(p.getage());
        System.out.println(p.getname());
    }

}

l 總結:

類中不需要對外提供的內容都私有化,包括屬性和方法。

以後再描述事物,屬性都私有化,並提供setXxx getXxx方法對其進行訪問。

l 注意:私有僅僅是封裝的體現形式而已。

(3)this關鍵字

方法中出現區域性變數和成員變數同名時,可以新增this關鍵字來進行區分,可以在成員變數名前面加上this.來區別成員變數和區域性變數

Public class Person {
    private int age;
    private String name;
    
    public void speak() {
        this.name = "小強";
        this.age = 18;
        System.out.println("name=" + this.name + ",age=" + this.age);
    }
}
Public class PersonDemo {
    public static void main(String[] args) {
        Person p = new Person();
        p.speak();
    }
}

物件的記憶體解釋

程式執行流程說明:

1、首先在資料和方法共享區讀取.class檔案,main方法。

2、 先執行main方法(壓棧),執行其中的 Person p = new Person();

3、看到new一個物件則 在堆記憶體中開闢空間,併為其分配記憶體地址0x000,緊接著成員變數預設初始化(age = 0);將記憶體地址0x000賦值給棧內中的Person p 變數

4、繼續執行p.setAge(30)語句,這時會呼叫setAge(int age)方法,將30賦值為setAge方法中的“age”變數;執行this.age = age語句,將age變數值30 賦值給成員變數this.age為30;

5、setAge()方法執行完畢後(彈棧),回到main()方法,執行輸出語句System.out.println(),控制檯列印p物件中的age年齡值。

4、繼承

(1)繼承的概述:

在程式中,繼承描述的是事物之間的所屬關係,通過繼承可以使多種事物之間形成一種關係體系。

例如:

類的繼承是指在一個現有類的基礎上去構建一個新的類,構建出來的新類被稱作子類,現有類被稱作父類,子類會自動擁有父類所有可繼承的屬性和方法。

格式:

public   class 子類 extends 父類 {  }

整合的舉例:

package damo03;

public class Fu {
    int a=6;
}
package damo03;
//在繼承中,成員變數的特點:
//如果父類成員變數和子類成員變數同名,那麼呼叫的是子類的成員變數
//在繼承中,子類只能繼承父類可繼承的成員,私有化的成員,可以繼承,但是沒法使用和操作,相當於沒繼承
public class ZI extends Fu{//------------------繼承父類
    int a=2;
    public void speak(){
        int a=3;
        System.out.println(this.a);
        System.out.println(super.a);
    }
}
package damo03;

public class Text1 {
public static void main(String[] args) {
    ZI bb=new ZI();
    bb.speak();
}
}

Zi類通過extends關鍵字繼承了Fu類。

子類雖然沒有定義int a=1;的屬性和work()方法,但是卻能訪問這這個成員。這就說明,子類在繼承父類的時候,會自動擁有父類的成員。

 繼承的好處與注意事項:

好處:

1、提高了程式碼的複用性,

2、繼承的出現讓類與類之間產生了關係,提供了多型的前提。

 注意事項:

1、在Java中,類只支援單繼承,不允許多繼承,也就是說一個類只能有一個直接父類 

class A{}

     class B{}

     class C extends A,B{}  // C不可以同時繼承A類和B

2、多個類可以繼承一個父類

 class A{}

     class B extends A{}

     class C extends A{}   // B和類C都可以繼承類A

(2)子父類中成員變數的特點

----------------Fu類中的成員變數是非私有的,子類中可以直接訪問,若Fu類中的成員變數私有了,子類是不能直接訪問的。當子父類中出現了同名成員變數時,在子類中若要訪問父類中的成員變數,必須使用關鍵字super來完成。super用來表示當前物件中包含的父類物件空間的引用。

在子類中,訪問父類中的成員變數格式:

super.父類中的成員變數

class Fu
{
    //Fu中的成員變數。
    int num = 5;
}
class Zi extends Fu
{
    //Zi中的成員變數
    int num = 6;
    void show()
    {
        //子父類中出現了同名的成員變數時
        //在子類中需要訪問父類中非私有成員變數時,需要使用super關鍵字
        //訪問父類中的num
        System.out.println("Fu num="+super.num); //訪問子類中的num2
        System.out.println("Zi num2="+this.num);
    }
}
class Demo5 
{
    public static void main(String[] args) 
    {
        Zi z = new Zi(); //建立子類物件
        z.show(); //呼叫子類中的show方法
    }
}

 (3)子類繼承父類的的方法特點:直接繼承和重寫

當在程式中通過物件呼叫方法時,會先在子類中查詢有沒有對應的方法,若子類中存在就會執行子類中的方法,若子類中不存在就會執行父類中相應的方法。

class Fu{-----------------------------------------------------------------------------父類
    public void show(){---------------------------------------------------------------show方法
        System.out.println("Fu類中的show方法執行");
    }
}
class Zi extends Fu{-------------------------------------------------------------------子類繼承父類的方法
    public void show2(){---------------------------------------------------------------子類的show2方法
        System.out.println("Zi類中的show2方法執行");
    }
}
public  class Test{
    public static void main(String[] args) {
        Zi z = new Zi();
        z.show(); //-------------------------------------------------------------------子類中沒有show方法,但是可以找到父類方法去執行
        z.show2();----------------------------------------------------------------------父類中沒有show方法,就執行的父類中的方法
    }
}

 成員方法特殊情況——覆蓋

子類中出現與父類一模一樣的方法時,會出現覆蓋操作,也稱為override重寫、複寫或者覆蓋。方法重寫

class Zi extends Fu
{
    //子類複寫了父類的show方法
    public void show()
    {
        System.out.println("Zi show");
    }
}

l 方法重寫(覆蓋)的應用:

當子類需要父類的功能,而功能主體子類有自己特有內容時,可以重寫父類中的方法,這樣,即沿襲了父類的功能,又定義了子類特有的內容。

例如:增加功能

比如手機,當描述一個手機時,它具有發簡訊,打電話,顯示來電號碼功能,後期由於手機需要在來電顯示功能中增加顯示姓名和頭像,這時

可以重新定義一個類描述智慧手機,並繼承原有描述手機的類。並在新定義的類中覆蓋來電顯示功能,在其中增加顯示姓名和頭像功能。

class Phone{--------------------------------------------屬性
    public void sendMessage(){
        System.out.println("發簡訊");
    }
    public void call(){
        System.out.println("打電話");
    }
    public void showNum(){
        System.out.println("來電顯示號碼");
    }
}
//智慧手機類
class NewPhone extends Phone{-----------------------繼承父類屬性
    
    //覆蓋父類的來電顯示號碼功能,並增加自己的顯示姓名和圖片功能
    public void showNum(){
        //呼叫父類已經存在的功能使用super
        super.showNum();
        //增加自己特有顯示姓名和圖片功能
        System.out.println("顯示來電姓名");
        System.out.println("顯示頭像");
    }
}
public class Test {
    public static void main(String[] args) {
        new NewPhone().showNum();
    }
}

注意:

l 子類方法覆蓋父類方法,必須要保證許可權大於等於父類許可權。

寫法上稍微注意:必須一模一樣:方法的返回值型別 方法名 引數列表都要一樣。

總結:當一個類是另一個類中的一種時,可以通過繼承,來繼承屬性與功能。如果父類具備的功能內容需要子類特殊定義時,進行方法重寫。