1. 程式人生 > >Java面向物件封裝和繼承

Java面向物件封裝和繼承

面向物件

什麼是面向過程、面向物件?

面向過程與面向物件都是我們程式設計中,編寫程式的一種思維方式。

  •   面向過程的程式設計方式,是遇到一件事時,思考“我該怎麼做”,然後一步步實現的過程。例如:公司打掃衛生(擦玻璃、掃地、拖地、倒垃圾等),按照面向過程的程式設計方式會思考“打掃衛生我該怎麼做,然後一件件的完成”,最後把公司衛生打掃乾淨了。
  •  面向物件的程式設計方式,是遇到一件事時,思考“我該讓誰來做”,然後那個“誰”就是物件,他要怎麼做這件事是他自己的事,反正最後一群物件合力能把事就好就行了。例如,公司打掃衛生(擦玻璃、掃地、拖地、倒垃圾等),按照面向物件的程式設計方式會思考“我該讓誰來做,如小明擦玻璃、讓小麗掃地、讓小郭拖地、讓小強倒垃圾等”,這裡的“小明、小麗、小郭、小強”就是物件,他們要打掃衛生,怎麼打掃是他們自己的事,反正最後一群物件合力把公司衛生打掃乾淨了。

舉例:

  • 買電腦(組裝機)

       先使用面向過程說明買電腦這件事:假如我們需要買組裝電腦,這時首先會在網上查詢具體每一個硬體的引數和報價。然後會去電腦城進行多家詢價,接著詢價結束後回家根據具體的結果分析出自己比較滿意的哪家報價,接著會到這家店裡進行組裝,組裝時還需要進行現場監督,組裝完成安裝相應的系統,然後電腦抱回家。

       分析上述整個過程大體分一下幾步:上網查詢引數和報價、電腦城詢價、現場安裝和監督、抱電腦回家。在整個過程中我們參與了每一個細節,並且會感覺相當累。

      使用面向物件說明買電腦這件事:假如我們需要買組裝機,這時應該找一個懂電腦硬體的人,讓他幫我們檢視引數和報價,並進行詢價和殺價,以及現場組裝監督。而我們自己並不需要親歷親為具體怎麼做,只要告訴這個人我們想要的具體需求即可。

       分析上述整個過程,發現瞬間變的十分輕鬆,只要找到懂電腦硬體的這個人,我們的問題都可以解決。並且在這個過程中我們不用那麼辛苦。

面向物件思維方式的好處:

通過生活中的真實場景使用面向物件分析完之後,我們開始分析面向過程和麵向物件的差異做出總結:

  •   面向物件思維方式是一種更符合人們思考習慣的思想
  •   面向過程思維方式中更多的體現的是執行者(自己做事情),面向物件中更多的體現是指揮者(指揮物件做事情)。
  •   面向物件思維方式將複雜的問題簡單化。

類和物件

在我之前的篇部落格中,詳細描述了類和物件,可以看看。

封裝

提起封裝,大家並不陌生。前面我們學習方法時,就提起過,將具體功能封裝到方法中,學習物件時,也提過將方法封裝在類中,其實這些都是封裝。

封裝,它也是面向物件思想的特徵之一。面向物件共有三個特徵:封裝,繼承,多型。接下來我們具體學習封裝。

封裝的表現:

 1、方法就是一個最基本封裝體。

  2、類其實也是一個封裝體。

 從以上兩點得出結論,封裝的好處:

  • 提高了程式碼的複用性。
  • 隱藏了實現細節,還要對外提供可以訪問的方式。便於呼叫者的使用。這是核心之一,也可以理解為就是封裝的概念。
  • 提高了安全性。

封裝舉例:

機箱:

一臺電腦,它是由CPU、主機板、顯示卡、記憶體、硬碟、電源等部件組長,其實我們將這些部件組裝在一起就可以使用電腦了,但是發現這些部件都散落在外面,很容造成不安全因素,於是,使用機箱殼子,把這些部件都裝在裡面,並在機箱殼上留下一些插口等,若不留插口,大家想想會是什麼情況。

總結:機箱其實就是隱藏了辦卡裝置的細節,對外提供了插口以及開關等訪問內部細節的方式。

私有private

瞭解到封裝在生活的體現之後,又要回到Java中,細說封裝的在Java程式碼中的體現,先從描述Person說起。

     描述人。Person

     屬性:年齡。

     行為:說話:說出自己的年齡。

class Person {
    int age;
    String name;

    public void show() {
        System.out.println("age=" + age + ",name" + name);
    }
}

public class PersonDemo {
    public static void main(String[] args) {
        // 建立Person物件
        Person p = new Person();
        p.age = -20; // 給Person物件賦值
        p.name = "美女";
        p.show(); // 呼叫Person的show方法
    }
}
View Code

通過上述程式碼發現,雖然我們用Java程式碼把Person描述清楚了,但有個嚴重的問題,就是Person中的屬性的行為可以任意訪問和使用。這明顯不符合實際需求。

可是怎麼才能不讓訪問呢?需要使用一個Java中的關鍵字也是一個修飾符 private(私有,許可權修飾符)。只要將Person的屬性和行為私有起來,這樣就無法直接訪問。

class Person {
    private int age;
    private String name;

    public void show() {
        System.out.println("age=" + age + ",name" + name);
    }
}
View Code

年齡已被私有,錯誤的值無法賦值,可是正確的值也賦值不了,這樣還是不行,那腫麼辦呢?按照之前所學習的封裝的原理,隱藏後,還需要提供訪問方式。只要對外提供可以訪問的方法,讓其他程式訪問這些方法。同時在方法中可以對資料進行驗證。

一般對成員屬性的訪問動作:賦值(設定 set),取值(獲取 get),因此對私有的變數訪問的方式可以提供對應的 setXxx或者getXxx的方法。

class Person {
    // 私有成員變數
    private int age;
    private String name;

    // 對外提供設定成員變數的方法
    public void setAge(int a) {
        // 由於是設定成員變數的值,這裡可以加入資料的驗證
        if (a < 0 || a > 130) {
            System.out.println(a + "不符合年齡的資料範圍");
            return;
        }
        age = a; 
    }

    // 對外提供訪問成員變數的方法
    public void getAge() {
        return age;
    }
}
View Code
  •   總結:

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

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

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

this關鍵字:

成員變數和區域性變數重名的問題:

可以在成員變數名前面加上this.來區別成員變數和區域性變數

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);
    }
}

class PersonDemo {
    public static void main(String[] args) {
        Person p = new Person();
        p.speak();
    }
}
View Code

物件記憶體的解釋:

這裡需要畫圖一步一步演示,嚴格按照畫圖流程講解記憶體物件建立使用過程。

class Person {
    private int age;
    public int getAge() {
        return this.age;
    }
    public void setAge(int age) {
        this.age = age;
    }
}
public class PersonDemo {
    public static void main(String[] args) {
        Person p = new Person();
        p.setAge(30);
        System.out.println("大家好,今年我" + p.getAge() + "歲");
    }
}
View Code

程式執行流程說明:

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

2、 在堆記憶體中開闢空間,併為其分配記憶體地址0x1234,緊接著成員變數預設初始化(age = 0);將記憶體地址0x1234賦值給棧內中的Person p 變數

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

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

  注意:

  this到底代表什麼呢?this代表的是物件,具體代表哪個物件呢?哪個物件呼叫了this所在的方法,this就代表哪個物件。

 上述程式碼中的 p.setAge(30)語句中,setAge(int age)方法中的this代表的就是p物件。

應用:

需求:在Person類中定義功能,判斷兩個人是否是同齡人

class Person {
    private int age;
    private String name;
    
    public int getAge() {
        return age;
    }

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

    public String getName() {
        return name;
    }

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

    public void speak() {
        System.out.println("name=" + this.name + ",age=" + this.age);
    }

    // 判斷是否為同齡人
    public boolean equalsAge(Person p) {
        // 使用當前呼叫該equalsAge方法物件的age和傳遞進來p的age進行比較
        // 由於無法確定具體是哪一個物件呼叫equalsAge方法,這裡就可以使用this來代替
        /*
         * if(this.age == p.age) { return true; } return false;
         */
        return this.age == p.age;
    }
}
View Code

現在總結this關鍵字:

  • this是在方法中使用的,那個物件呼叫了該方法,那麼,this就代表呼叫該方法的物件引用
  • this什麼時候存在?當建立物件的時候,this存在
  • this的作用:用來區別同名的成員變數與區域性變數(this.成員變數)
public void setName(String name) {
                this.name = name;
 }

繼承

概念:

在現實生活中,繼承一般指的是子女繼承父輩的財產。在程式中,繼承描述的是事物之間的所屬關係,通過繼承可以使多種事物之間形成一種關係體系。例如公司中的研發部員工和維護部員工都屬於員工,程式中便可以描述為研發部員工和維護部員工繼承自員工,同理,JavaEE工程師和Android工程師繼承自研發部員工,而維網路維護工程師和硬體維護工程師繼承自維護部員工。這些員工之間會形成一個繼承體系,具體如下圖所示。

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

繼承的格式和使用

格式:
class 子類 extends 父類 {}

接下來通過一個程式碼來學習子類是如何繼承父類的

/*
 * 定義員工類Employee
 */
class Employee {
    String name; // 定義name屬性
    // 定義員工的工作方法
    public void work() {
        System.out.println("盡心盡力地工作");
    }
}

/*
 * 定義研發部員工類Developer 繼承 員工類Employee
 */
class Developer extends Employee {
    // 定義一個列印name的方法
    public void printName() {
        System.out.println("name=" + name);
    }
}

/*
 * 定義測試類
 */
public class Example01 {
    public static void main(String[] args) {
        Developer d = new Developer(); // 建立一個研發部員工類物件
        d.name = "小明"; // 為該員工類的name屬性進行賦值
        d.printName(); // 呼叫該員工的printName()方法
        d.work(); // 呼叫Developer類繼承來的work()方法
    }
}
View Code

在上述程式碼中,Developer類通過extends關鍵字繼承了Employee類,這樣Developer類便是Employee類的子類。從執行結果不難看出,子類雖然沒有定義name屬性和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

 3、在Java中,多層繼承是可以的,即一個類的父類可以再去繼承另外的父類,例如C類繼承自B類,而B類又可以去繼承A類,這時,C類也可稱作A類的子類。下面這種情況是允許的。

class A{}
     class B extends A{}   // 類B繼承類A,類B是類A的子類
     class C extends B{}   // 類C繼承類B,類C是類B的子類,同時也是類A的子類

  4、在Java中,子類和父類是一種相對概念,也就是說一個類是某個類父類的同時,也可以是另一個類的子類。例如上面的這種情況中,B類是A類的子類,同時又是C類的父類。

繼承-子父類中的成員變數的特點:

瞭解了繼承給我們帶來的好處,提高了程式碼的複用性。繼承讓類與類或者說物件與物件之間產生了關係。那麼,當繼承出現後,類的成員之間產生了那些變化呢?

成員變數:如果子類父類中出現不同名的成員變數,這時的訪問是沒有任何問題。

class Fu
{
    //Fu中的成員變數。
    int num = 5;
}
class Zi extends Fu
{
    //Zi中的成員變數
    int num2 = 6;
    //Zi中的成員方法
    public void show()
    {
        //訪問父類中的num
        System.out.println("Fu num="+num);
        //訪問子類中的num2
        System.out.println("Zi num2="+num2);
    }
}
class Demo 
{
    public static void main(String[] args) 
    {
        Zi z = new Zi(); //建立子類物件
        z.show(); //呼叫子類中的show方法
    }
}
View Code

程式碼說明: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方法
    }
}
View Code

繼承-子父類中成員方法特點-重寫和應用

子父類中成員方法的特點

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

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

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

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

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

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

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

舉例:比如手機,當描述一個手機時,它具有發簡訊,打電話,顯示來電號碼功能,後期由於手機需要在來電顯示功能中增加顯示姓名和頭像,這時可以重新定義一個類描述智慧手機,並繼承原有描述手機的類。並在新定義的類中覆蓋來電顯示功能,在其中增加顯示姓名和頭像功能。

在子類中,訪問父類中的成員方法格式:
super.父類中的成員方法();
public class Test {
    public static void main(String[] args) {
        new NewPhone().showNum();
    }
}

//手機類
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("顯示頭像");
    }
}
View Code

方法重寫的注意事項:

  • 子類方法覆蓋父類方法,必須要保證許可權大於等於父類許可權。
    class Fu(){    
    void show(){}
        public void method(){}
    }
    class Zi() extends Fu{
    public void show(){}  //編譯執行沒問題
        void method(){}      //編譯錯誤
    }
    View Code
  • 寫法上稍微注意:必須一模一樣:方法的返回值型別 方法名 引數列表都要一樣。

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

相關推薦

Java面向物件封裝繼承

面向物件 什麼是面向過程、面向物件? 面向過程與面向物件都是我們程式設計中,編寫程式的一種思維方式。   面向過程的程式設計方式,是遇到一件事時,思考“我該怎麼做”,然後一步步實現的過程。例如:公司打掃衛生(擦玻璃、掃地、拖地、倒垃圾等),按照面向過程的程式設計方式會思考“打掃衛生我該怎麼做,然後一件件的完

Java面向物件----封裝概念

封裝   資訊隱藏,隱藏物件的細節 訪問修飾符 public   private   protected    預設 屬性封裝的實現 方法封裝的目的(隱藏方法實現細節) package com.tanlei.newer; public clas

js面向物件原型繼承

js面向物件原型和繼承作用域鏈和閉包 原型 我們都知道,函式建立時瀏覽器會在記憶體中建立一個物件。很多人在這裡都感覺很難理解裡面的關係 函式建立的時候,瀏覽器會在記憶體中建立一個由prototype指向的物件。其實只有當你要將函式作為建構函式使用的時候,創建出來的物件才會發揮作用

java面向物件-包許可權修飾符

1.包和許可權修飾符 1.1包的概述        java的包,其實就是我們電腦系統中的資料夾,包裡存放的是類檔案。 1.2包的宣告格式        通常使用公司網址反寫,可以有多層包,包名採用全

java 面向物件 封裝

1.封裝是什麼?以及為什麼要進行封裝? 通常情況下可以給成員變數賦值一些合法但不合理的數值,這種情況在編譯階段和執行階段都不會報錯或給出任何的提示資訊,此數值雖然合法但與現實生活不符;為了避免上述問題的發生,就需要對成員變數進行密封包裝處理來保證該成員變數的合法

面向物件封裝繼承、多型

多型(Polymorphism):意味著可以對不同類的物件使用相同的操作。 封裝(Encapsulation): 即對外部世界隱藏物件的工作細節。 繼承(Inheritance): 以通用的類為基礎建立專門的類物件。 1.封裝 顧名思義就是將內容

5本最佳的Java面向物件理論設計模式的書籍

對於Java程式設計師來說,掌握面向物件的設計理論和一些設計模式是必備技能。就像我在另一篇部落格Java程式設計師應該知道的10個面向物件理論中提到的,不學理論就開始程式設計,就類似於學習一種語言而不學習字母表。市面上有很多有關面向物件理論的、設計模式的和最佳實踐的,但只有很

JAVA面向物件 類的繼承

本頁面更新日期: 2016年07月30日 前言 繼承是面向物件的三大特徵之一. 也是實現軟體複用的重要手段. Java繼承具有單繼承的特點, 每個子類只有一個直接父類. 繼

面向物件——封裝繼承、多型

封裝 概念:將類的某些資訊隱藏在類的內部,不允許外部程式直接訪問,而是直接通過該類提供的方法來實現對隱藏資訊的操作與訪問 好處: a. 只能通規定的方法訪問資料 b. 隱藏類的例項細節,方便

java面向物件封裝

封裝:是指隱藏物件的屬性和實現細節,僅對外提供公共訪問方式。 封裝好處:隱藏實現細節,提供公共的訪問方式,提高了程式碼的複用性,提高安全性。 private關鍵字:是一個許可權修飾符、可以修飾成員變數和成員方法、被其修飾的成員只能在本類中被訪問 private最常見的應用:(1

python面向物件--私有繼承

一、 私有屬性和私有方法 應用場景 在實際開發中,物件的某些屬性或方法可能只希望在物件的內部使用,而不希望在外部被訪問到 私有屬性 就是 物件 不希望公開的屬性 (屬性即類裡面的變數) 私有方法 就是 方法 不希望公開的方法 定義方式 在定義屬性或方法時,在屬性名或者方法名前新增兩個下劃線,定義的

學習Java面向物件程式設計設計模式最好的5本書

對於任何一個Java開發人員來說,必須學會面向物件的設計原則和各種設計模式的知識。但有一些關於面向物件設計原則、設計模式和最佳實踐的書籍,只有少數幾本書能做到真正在講解這方面內容。 設計原則和設計模式,設計原則是基礎,設計模式是基於這個基礎的最佳實踐。首先應該學習面向物件的理論原則,然後學習設計

javaScript 面向物件--封裝prototype屬性

一般面向物件的語言都具有三大特徵,封裝、繼承,多型,例如像java 和c++。但是javaScript它可以說不是完全的面向物件的語言,因為它沒有類的概念,但是它又是面向物件的,因為它可以封裝屬性和方法,並且也可以實現繼承。 1、字面量模式 字面量的模式

Java面向物件——類物件

java面向物件的三大特徵:封裝、繼承和多型。 類與物件 所有類是引用資料型別。 對於一個類定義而言,包含三種最常見的成員:構造器、屬性、方法,三 種成員可以定義多個或零個,當為零個時,

Java面向物件——類的繼承

1.繼承的定義以及基本使用 定義:子類能夠繼承父類的共有屬性和方法; 特點:Java中只支援單繼承,私有方法不能被繼承;            實現繼承的類被稱為子類(也叫派生類),被繼承的類被稱為父類(也叫基類).             Java的繼承通過exte

java面向物件---介面抽象的簡單練習

1、有一批電腦,電腦有三種品牌,每個品牌都是組裝機,都會用到顯示卡\記憶體\cpu,這些顯示卡\記憶體\cpu又有不同品牌的廠家生產,請組裝出惠普、聯想、蘋果這三臺電腦 簡單實現(設計思路) /** * 電腦抽象類 */ abstract clas

Java面向物件思想特徵

java面向物件思想 java面向物件思想是一種程式設計思想,計算機程式設計的實質就是把現實生活中的一些事物的特徵抽離出來描述成一些計算機事件的過程,這種抽象的過程中,我們把具體的事物封裝成一個一個的整體進行描述,使被描述的物件具備一些系統性、整體性的特徵和行

java面向物件思想三大特性

面向物件:    1、面向物件 面向物件是一種程式設計思想,計算機程式的設計實質上就是將現實中的一些事物的特徵抽離出來描述成一些計算機事件的過程,這種抽象的過程中,我們把具體的事物封裝成一個一個的整體進行描述,使被描述的物件具備一些系統性、整體性的的行為和特徵,我們把

Java面向物件概述及三大特徵(封裝繼承多型)

一、面向物件思想 Java是面向物件的高階語言,對於Java語言來說,萬事萬物皆物件! 它的基本思想是使用類,物件,繼承,封裝,訊息等基本概念進行程式設計。面向物件程式的最小單元是類,類代表了客觀世界中具有某一特徵的一類事物,封裝了這類事物所具有的屬性和行為。 所以,類定義=成員變數(屬性)+方法(行為

黑馬程式設計師--Java學習日記之面向物件(封裝,繼承構造方法)

------- android培訓、java培訓、期待與您交流! ---------- 面向物件思想:     面向過程,以函式為基礎,關注的是實現過程;     面向物件,以物件為基礎,關注的是最終結果; 面向物件思想特點         是一種更符合我們思想習慣的思想