iT邦幫忙

2021 iThome 鐵人賽

DAY 4
2

修飾符(Modifier)

  上一篇有講到封裝的特性,也就是把一個類別要運行操作所需用到的資訊都包在一起,其中這些資訊的存取權限設定就相對重要,透過修飾符就可以控制資訊能夠給誰使用、誰不能用,這樣就能提高系統的安全性與完整。(修飾符可以套在方法或是類別之前)

  常見修飾符分為以下幾種:

  1. public-即公開,如字面上所示,存取權限是最大的,只要套上這個修飾符,所有人的可以去使用。
  2. private-這個修飾符是存取權限最小的,只有類別自己本身可以去使用,要把資料隱藏就會需要用到這個。
  3. protected-保護這個修飾符一旦套上的話,就只有父類別與子類別才能夠去做存取的動作。
  4. 沒有修飾符-都沒有套上和修飾符的話,那就是在同一個 package 裡的類別都可以去使用
class Employee {
    int ID;
    protected String name;
    private int age;

    public Employee(int id, String name, int age) {
        ID = id;
        this.name = name;
        this.age = age;
    }

    public void selfIntrodution() {
        System.out.println("我的名子叫" + name + ",今年" + age + "歲!");
    }
}

class Engineer extends Employee{
    private String position = "工程師"
}

public class Company {

    public static void main(String []args) {
        Engineer Jack = new Engineer(123, "Jack", 30);
                
        Jack.selfIntrodution();
        System.out.println(Jack.name);
        System.out.println(Jack.age);
        System.out.println(Jack.ID);
    }
}

  如上面的程式範例所示,我們宣告了Jack為工程師類別,呼叫了父類別的selfIntrodution()方法,修飾符為public,任何類別皆可存取,這行沒有問題。再來存取父類別的屬性(name),修飾符為protected,而它們的關係是父子類別,這行也沒有問題。接著試著去存取父類別的屬性(age),修飾符為private,這表示只有父類別自己本身才能存取的屬性,子類別沒有存取的權限,所以編譯會有錯誤,Jack能存取的private屬性只有自己的position。最後去存取父類別的屬性(ID),沒有特定的修飾符,表示所有在此package的類別皆可存取,這行也就沒有問題。

抽象類別(Abstract Class)

  關於抽象類別有幾個重點:

  1. 抽象類別沒辦法被宣告成物件(實例化)。
  2. 如果此類別有抽象方法的話,那這個類別必須為抽象類別。
  3. 抽象類別的子類別必須複寫所有的抽象方法。
abstract class Employee {
    protected int ID;
    protected String name;
    protected int age;

    public Employee(int id, String name, int age) {
        ID = id;
        this.name = name;
        this.age = age;
    }

    abstract void selfIntrodution();
}

class Engineer extends Employee{
    
    public Engineer(int id, String name, int age) {
        super(id, name, age);
    }
    
    public void selfIntrodution() {
        System.out.println("我是一位工程師");
    }
}

class Accountant extends Employee{
    
    public Accountant(int id, String name, int age) {
        super(id, name, age);
    }
    
    public void selfIntrodution() {
        System.out.println("我是一位會計師");
    }
}

  

  我在員工類別前面加了「abstract」,這就代表這是一個抽象類別,而抽象類別可以擁有抽象方法(selfIntrodution()),它可以不用去定義它的實作方式,要在子類別去複寫。

  

介面(Interface)

  認識了抽象類別後,一定要在認識一下介面(Interface),介面封裝了一些特定的功能,只要有類別實作此介面,就可以使用介面所有的屬性和方法,現在請看以下範例程式碼:

interface habit {
    void interest();
}

abstract class Employee {
    protected int ID;
    protected String name;
    protected int age;

    public Employee(int id, String name, int age) {
        ID = id;
        this.name = name;
        this.age = age;
    }

    abstract void selfIntrodution();
}

class Engineer extends Employee implements habit{
    
    public Engineer(int id, String name, int age) {
        super(id, name, age);
    }
    
    public void selfIntrodution() {
        System.out.println("我是一位工程師");
    }
    
    public void interest() {
        System.out.println("我愛寫程式");
    }
}

class Kid implements habit {
    
    public void interest() {
        System.out.println("我愛看電視");
    }
}

public class Program {

    public static void main(String []args){
        Engineer Jack = new Engineer(123, "Jack", 30);
        Kid Connie = new Kid();
                
        Jack.interest();
        Connie.interest();
    }
}

//    result:
//        我愛寫程式
//        我愛看電視

  我們可以看到工程師類別除了繼承了員工類別外,還實作了習慣介面,另外小孩類別也實作了習慣介面,兩個類別分別定義了介面的方法(interest()),分別是「我愛寫程式」與「我愛看電視」。

  看到這裡也許會有個疑問:已經有了抽象類別封裝好共同需要的屬性與方法,為甚麼還需要再多個介面來封裝呢?

  答案就是當我們有兩個以上的具體類別,但它們卻不屬於同一類別,就像是程式範例一樣,工程師屬於員工的一種,所以它繼承了員工的屬性;而小孩卻不屬於任何類別,但卻又與工程師擁有「習慣」,因此我們把習慣寫成介面,並讓他們兩個可以實作。換句話說,當我們在設計程式的時候,若有發現不同的類別有重複的內容,那就可以把這些重複的內容封裝到抽象類別中,然後再由這些類別(子類別)去繼承抽象類別(父類別);而介面是發現不同父類別中的子類別之間,有重複的特徵,因此把這些特徵封裝到介面裡,再由這些子類別去實作。

  簡單來說,此特徵是在不同類的物件發生,那就用介面實作;若在相似的類別發生,就用抽象類別去繼承。

  有父類別的概念後,我們就可以不用再一直寫相同的程式碼在不同的類別上,而且修改父類別,子類別也會跟著修改,就不需要每一個類別都改過,維護程式就變得簡單多了;了解了修飾符後,可以讓類別封裝得更加完整、更具安全性。

  物件導向的基本概念就介紹到這邊,接下來會說明在學習 Design Pattern 前需要了解的一些知識,這樣就可以在學習的時候更快了解 Pattern 的架構與應用方式。


除此之外,也歡迎大家走走逛逛關於我們團隊夥伴的文章
lu23770127 - SASS 基礎初學三十天
10u1 - 糟了!是世界奇觀!
juck30808 - Python - 數位行銷分析與 Youtube API 教學
SiQing47 - 前端?後端?你早晚都要全端的,何不從現在開始?


上一篇
IT鐵人DAY 3-物件導向基本概念(2)
下一篇
IT鐵人DAY 5-MVC 介紹
系列文
淺談物件導向與Design Pattern介紹30
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言