JAVA筆記 _ OOP的三大特性


封裝

一般來說封裝就是將class用private隱藏內部資料, 並且以public方法提取/修改
簡單來說即屬性私有 get/set方法 符合高內聚低耦合的程式撰寫方式
最大程度只讓別人看到該看的東西, 剩下的東西全部包起來不給看
優點來說:

  • 保護內部資料不被非法竄改取用
  • 使用單一入口取用更改object之資料值
  • get/set方法可以在使用者輸入時做檢查是否合法之動作

    class語法構造

    public class Student{
      //class屬性
      private int age;
      private String name;
    
      //class方法
      public void setAge(int a){
          if(a>120 || a<0) this.age=10;
          else this.age=a;
      }
      public void setName(int n){
          this.name=n;
      }
    }
    

    顯示結果

    public static void main(String[] args){
      Student s1= new Student(); //new的當下即配置記憶體空間供object使用
      s1.setName("N");
      System.out.println(s1.getName()); //N
    }
    

建構子 constructor

當創立物件並且使用new這個關鍵字時,便表示我們分配記憶體空間供object使用,並且自動呼叫其class的constructor用來進行一些初始資料設定,此時才是真正的建立一個物件
constructor:

  • 為和class名稱一樣的方法
  • 必為public, 且無回傳型態和回傳值

      public class Student{
          //class屬性
          private int age;
          private String name;
    
          //construtor
          public Student(int a,int n){
              this.setAge(a);
              this.setName(n);
          }
    
          //class方法
          public void setAge(int a){...}
          public void setName(int n){...}
    }
    

    建構子有以下幾點必須注意:

    • 如果class無constructor, 則會在new object時自動補上public ClassName(){}之建構子,不帶任何參數
    • 如class有帶參數之constructor, class並不會自動生成無參數之constructor可使用,需要自己新增
    • 如constructor中有引用父類別之super(),則必須在constructor方法中擺在第一行

繼承

原則上只要子類別以extends繼承父類別,就可以擁有父類別的方法和屬性
public subclass extends superclass
但是以下並不能繼承:

  • 父類別的private方法和屬性 -->屬性使用父類別之get/set方法 方法沒救惹@@
  • 父類的建構子 -->subclass方法中以super(datatype1 v1,datatype2 v2)方法使用
  • 父類別static方法/屬性
  • 父類別final屬性

Override / Overload

由於有很多繼承自父類別的方法並不適合子類別使用,子類別若想使用同名異式的方法,則需要覆寫(override)/隱藏(overload)
方法:
override: 與父類別物件方法同名,同回傳型態,同參數列
overload: 與父類別類別方法(static)同名,不一定同回傳型態,不一定同參數列
屬性:
override/overload: 只要名稱相同就行, 資料型態不一定

多型

同一個名稱的method我們可以透過object的class差異而達到不同行為方式,也為一種同名異式
一個object的實際class是固定的,但是指向object的class操作指標可以改變
多型存在條件:

  • 子類別繼承父類別並且發生override
  • 以父類別指標操作子類別object
    Father f1=new Son();

superclass & subclass

public class person{
    public void say(){
        System.out.println("Person!");
    }
}

public class student extends person{
    public void say(){  //override
        System.out.println("Student!");
    }
    public void learn(){
        System.out.println("Study!");
    }
}

main code

public static void main(String args[]){
    Student s1=new student();
    person s2=new student();

    s1.say(); //Student!
    s1.learn(); //Study!
    s2.say(); //Student! override讓父類別指標使用子物件的方法-->多型
    s2.learn(); //Error 父類指標不能引用子類物件中擴充的功能
    ((student)s2).learn(); //Study! 強制轉型使用子類物件擴充功能
}

多型雖然可以用父類指標操作子類物件,但是不能操作那些子類自己另外擴充的方法或是屬性,在此我們必須提到物件等級特性:
class等級排序: supercalss > subclass
class內容多寡: subclass > superclass
可以用較高等級排序的class指標操作較低等級排序的class object(也可以相反
這種操作方式稱為參考(instanceof)
A類別指標 參考 B物件實際class 來操作object
多型則是為: 父類別指標 參考 子類別實際class 來操作object

物件轉型

但是其中有擴充的內容superclass指標卻不能操作
e.g. Father f1=new Son(); f1不能操作 Son()的擴充功能
這時便要用到物件轉型觀念:
注意object是用操作自己的class指標去相比較等級

  • 向上轉型: object採用父類class指標操作 會丟失已擴充方法
    student obj=new student();
    person p=student; //student-->person
    
  • 向下轉型: object採用子類class指標操作 需要強制轉型 會增加擴充方法
    person obj=new student();
    student s=(student) obj; //強制轉型 person-->student
    
    <各人總結>
    向上向下使用操作此object的class指標變化來決定
    向上轉型代表會缺少一些擴充function 之接轉換切除用不到強制轉型
    向下轉型代表會多一些擴充function可以用 因此要強制轉型擴充一下空間

參考 instanceof

A類別指標 參考 B物件實際class 來操作object,稱此為參考
if(A instanceof B) 會回傳true/false
true表示A B物件之間有繼承的上下關係,A物件為B物件的父類或同類,可以用其class指標操作B類物件


同場加映

abstract 抽象

子類override代表父類方法不適用, 則我們可以創立沒有內容的抽象概念框架,再由子類去繼承後實作出來

抽象class特色:

  • 無法new物件,只能參考子類別物件new object
  • 抽象class中可以有普通方法
  • 一旦class中有抽象方法, 此class必為抽象class
public abstract class Action{
    public abstract void dosomething(); //抽象方法 子類別必須規範好方法實作內容
    public void realaction(){...} //一般方法
}

interface 介面

將框架及實作徹底分離,實作的類別要將方法全部實作出來
介面特性:

  • 方法只有abstract方法
  • 不能以interface new object出來
  • 實作類別以 implements 實作interface的內容, 可以implements多個interface
    public interface UserService{
      void add(string name);  //默認是abstract function
      void delete(string name); //默認是abstract function
    }
    
public class user implements UserService{
    void add(string name){...}
    void delete(string name){...}
}
#OOP淺談






你可能感興趣的文章

[ JavaScript 06 ] function 傳參數的運作機制

[ JavaScript 06 ] function 傳參數的運作機制

linux螢幕解析度

linux螢幕解析度

20. Observer

20. Observer






留言討論