1. 程式人生 > >類,物件,面向物件以及三大特徵

類,物件,面向物件以及三大特徵

一、  類和物件
面向物件程式設計中兩個重要的概念:類和物件

1、簡單來說:物件的抽象化是類,類的具體化就是物件。類是一種抽象的概念,是對現實生活中事物的描述,類是對某一批物件的抽象,它不是實際存在的事物。物件是一個實際存在的實體,從這個意義上講,萬物都是物件。我們日常所說的人,都是人的例項,而不是人類。

2、現實中是先有物件,然後對這些物件進行描述,對物件的屬性和方法進行抽取形成類。在Java語言中,用來事物的方式是:先定義類,然後通過類建立例項化的物件。類就好比生產汽車要用的“圖紙”,圖紙中包含汽車實體所需要的資料和方法,然後用圖紙生產汽車。類和物件兩個概念對映發到Java中,類就是用class定義的類,具體物件就是Java在記憶體中用new關鍵字建立的實體。

類例項化物件的程式碼演示:
class Car//生產汽車所用的圖紙:就好比Java中類的概念
{
    String color;
    int wheelnum;
    
    public void method()
    {
        System.out.println("自動擋");
    }
}
class Demo
{
    public static void main(String[] args)
    {
        Car c = new Car();//用圖紙生產出的汽車:就好比Java中物件的概念
    }
}
二、  面向物件
因為面向物件是在面向過程的基礎上發展而來的,所以圍繞著面向過程和麵上物件展開對面向物件程式設計的簡單分析。

用如下三個例子分析面向物件:

1)、 “豬八戒吃西瓜”

在面向過程的世界裡,一切以函式為中心,函式最大,因此這件事情會用此語句表達:吃(豬八戒.西瓜);

在面向過程的世界裡,一切以物件為中心,物件最大,因此這件事情會用此語句表達:豬八戒.吃(西瓜);

     對比兩條語句不難發現,面向物件的語句更加接近自然語言的語法,主語,謂語,賓語一目瞭然,十分直觀,因此程式設計師更易理解。

2)、 “將大象放進冰箱裡”

        面向過程思想:強調的是一個過程:開啟冰箱,儲存大象,關閉冰箱

        面向物件思想:強調的是這個冰箱物件:冰箱開啟,冰箱儲存大象,冰箱關閉我們把(開啟,儲存,關閉)的功能儲存在冰箱這個物件中。

3)、 “給電腦除塵”

        面向過程的思想:你自己買一套拆電腦的工具,然後自己摸索著把電腦拆開,卸下風扇,清理掉風扇上的灰塵,最後裝上電腦後蓋。

          面向物件思想:你把電腦拿到電腦維修店,付錢給老闆後說半個小時後來取,然後你就回家吃飯了。吃完飯,過來取回除過塵的電腦你就可以繼續使用電腦。在這個過程中,你面向的就是“電腦維修員”這個物件。你不需要自己進行除塵這個複雜的過程,相當於呼叫了“電腦維修員”這個物件。                                    

“給電腦除塵”面向過程程式碼演示:

class Myself
{
    public static void main(String[] args)
    {
        System.out.println("開啟電腦後蓋");//我自己開啟電腦後蓋
        System.out.println("取出風扇除塵");//我自己取出風扇除塵
        System.out.println("關閉電腦後蓋");//我自己裝上電腦後蓋
    }
}
“給電腦除塵” 面向物件程式碼演示:
class Worker
{
    private String tool = "工具";
    //私有資料,只能由本類成員直接訪問。
    private static void method()
    {
        System.out.println(tool+"開啟電腦後蓋");
        System.out.println(tool+"取出風扇除塵");
        System.out.println(tool+"關閉電腦後蓋");
    }
    //公共方法暴露該物件的功能,在其他類中呼叫
    public void run()
    {
        method();
    }
}
class Myself
{
    public static void main(String[] args)
    {
        Worker w = new Worker();
        w.run();//呼叫對外暴露的公共方法。
    }
}
三、  面向物件的三大特徵
1、封裝
封裝:是指隱藏物件的屬性和實現細節,僅對外提供公共訪問方式。

封裝的意義:將變化隔離;便於使用;提高複用性;更加安全。

封裝的原則:將不需要對外暴露的內容都隱藏起來,提供公共方法讓其他類對其訪問。

給電腦除塵的例子中,“電腦維修員”是一個物件,他具有開啟電腦後蓋,取出風扇除塵,給電腦裝上後蓋等技術。至於這些技術是怎麼運用的,我們不知道。我們問他,他也不告訴我們。他的這些技術就好比類中的私有資料。但是他在店門口貼了一張廣告:電腦除塵。這個廣告就好比他暴露出來的公共方法。於是我們只要找到這個物件,然後自己呼叫這個公共方法即可完成對電腦的除塵。封裝的這一特性:首先,除塵這件事對我自己來說變得簡單了,另外我從之前的執行者(自己動手給電腦除塵)變成了指揮者(讓別人給電腦除塵)。
2、繼承:
父類和子類的關係,好比普通和特殊的關係。當子類繼承父類後,子類可以獲取父類中的屬性和方法。繼承是面向物件實現軟體複用的重要手段。

繼承的程式碼演示:

class Person
{
    private int age;
    private String name;
    Person(int age, String name)
    {
        this.age = age;
        this.name = name;
    }
    public void getAge()
    {
        System.out.println(age);
    }
    public void getName()
    {
        System.out.println(name);
    }
}
class Man extends Person
{
    Man(int age, String name)
    {
        super(age,name);
    }
}
class Demo
{
    public static void main(String[] args)
    {
        Man m = new Man(22,"ZhangSan");
        
        m.getAge();
        m.getName();
    }
}
注意:子類Man繼承父類Person中的所有屬性和方法,包括private。但是其中私有屬性需要子類呼叫從父類繼承來的公共方法才能對其訪問。

繼承中的注意事項:

1)、 子類中所有的建構函式都會預設訪問父類中的空引數的建構函式,因為每一個子類構造內第一行都有預設的語句super();如果父類中沒有空引數的建構函式,那麼子類的建構函式內,必須通過super語句指定要訪問的父類中的建構函式; 如果子類建構函式中用this來指定呼叫子類自己的建構函式,那麼被呼叫的建構函式也一樣會訪問父類中的建構函式。

2)、 繼承中往往會伴隨著方法的覆蓋,此時必須保證:子類方法的訪問許可權>=父類方法的訪問許可權。

重寫(Override)的特點:

1)、也叫複寫或者覆蓋,發生在子父類或者實現類和介面中。

2)、方法的返回值型別相同,方法名相同,引數列表相同。

3)、當需要被重寫的方法是static方法時,重寫的方法也必須是static,否則編譯失敗。

4)、重寫方法的訪問許可權>=被重寫方法的訪問許可權,否則編譯失敗。

過載(Overload)的特點:發生在同一個類或介面中,若干個方法,它們的方法名相同,引數列表不同,對返回值型別沒有要求,這種現象叫做過載。

3、多型
多型概念:Java引用變數又兩種型別:一種是編譯時型別,一種是執行時型別。編譯時型別由宣告該變數時使用的型別決定,執行時型別由實際賦給該變數的物件決定。

如果編譯時型別和執行時型別不一致,就可能出現所謂的多型了。(兩個重要概念,編譯時型別、執行時型別)。

多型的程式碼演示:

class Animals
{
    int x = 2;
    public void eat()
    {
        System.out.println("吃");
    }
    public static void sleep()
    {
        System.out.println("睡");
    }
}
class Cat extends Animals
{
    int x = 4;
    public void eat()
    {
        System.out.println("吃魚");
    }
    public static void sleep()
    {
        System.out.println("打呼嚕睡");
    }
    public void work()
    {
        System.out.println("抓老鼠");
    }
    
}
class Demo
{
    public static void main(String[] args)
    {
        Animals a = new Animals();
        a.eat();//列印吃        
        Animal ac = new Cat();
        ac.eat();//ac呼叫子父類共有的方法:列印吃魚
        
        System.out.println(ac.x);//ac訪問成員變數:列印2
        ac.sleep();//ac呼叫靜態成員:列印睡
        //ac.work();//編譯失敗,因為Animal型別沒有work方法
    }
}
由程式碼可見,a和ac都是Animal型別的變數,呼叫同一個方法時呈現除了不同的特性,這就是多型。

注意:

1)、引用變數在訪問它所包含的成員變數時,系統總是試圖訪問它編譯時的型別所定義的成員變數,而不是他執行時型別所定義的成員變數,所以成員變數不具備多型性。

2)、靜態成員方法附屬於類,多型的發生涉及到物件,所以靜態成員不具備多型性。

3)、當出現多型時,引用變數只能呼叫引用變數所屬類中的方法。如果該方法也在引用變數指向的物件中有定義,則執行物件中的方法;否則執行引用變數所屬類中的方法。比如:上邊程式碼中ac只能呼叫eat,sleep方法,不能呼叫work方法。並且ac呼叫eat方法時,執行的是吃魚的動作。

總結:

         成員變數和靜態成員沒有多型性,所以編譯和執行都看左邊(引用型變數所屬的類)。

         非靜態成員方法具有多型性,所以編譯看左邊執行看右邊(引用變數指向的物件)。
--------------------- 
轉載:https://blog.csdn.net/lilibaobei1314/article/details/37747173