星期一, 10月 08, 2012

OCPJP Day 7


Lab: 封裝 Customer 類別

如何利用 Netbeans 封裝
在編輯器上面按滑鼠右鍵 → Refactor → Encapsulate Fields → 點選 Select All → 點選 Refactor

如何利用 Netbeans 新增 Constructor 或是 toString()
在編輯器上面按滑鼠右鍵 → Insert Code → 選取 Constructor 或是 toString → 選取Fields → 點選 Generate

//滑鼠右鍵 → Refactor → change Method Parameters ( 可以改變參數的順序)
//滑鼠右鍵 → Format 可以將沒有縮排或是沒有排好的 code 自動排好

Customer.java 內容如下

package mod08;

public class Customer {

private int id;
private String name;
private char gender;
private int age;
private boolean married;

// 在編輯器上面按滑鼠右鍵 --> Insert Code --> Constructor
public Customer(int id, String name, char gender, int age, boolean married) {
this.id = id;
this.name = name;
this.gender = gender;
this.age = age;
this.married = married;
}

// 在編輯器上面按滑鼠右鍵 --> Insert Code --> toString()
@Override
public String toString() {
return "Customer{" + "id=" + id + ", name=" + name + ", gender=" + gender + ", age=" + age + ", married=" + married + '}';
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

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

public char getGender() {
return gender;
}

public void setGender(char gender) {
if (gender == 'M' || gender == 'F') { //必須為 M 或是 F 不然就設定為 U
this.gender = gender;
} else {
this.gender = 'U';
}
}

public int getAge() {
return age;
}

public void setAge(int age) {
if (age >= 0 && age <= 150) { //年齡必須大於0 並小於 150
this.age = age;
} else {
this.age = 0;
}
}


public boolean isMarried() {
return married;
}


public void setMarried(boolean married) {
this.married = married;
}
}


TestCustomer.java 內容如下

package mod08;

public class TestCustomer {

public static void main(String[] args) {
Customer c1 = new Customer();
c1.setAge(14);
System.out.println(c1);
//Customer 內的參數如下 id / name / gender / age / married
Customer c2 = new Customer(2,"max",'F',15,true); //這邊 char 要使用 單引號來標示
System.out.println(c2);
//這邊會發現如果是直接使用Constructor 餵參數進去, 不會被檢查判斷式
//所以可以在建構子那邊改為 setGender 來進行檢查 (會有風險)
Customer c3 = new Customer(3,"ines",'O',200,false);
System.out.println(c3);
}
}



Notes:
  • Netbeans 不能在產生建構子的時候調整參數的順序



*Chapter 9 繼承

Problem Statement 問題描述

SRS (System Requirement Specification) 系統需求規格書

Notes:
  • 類別的由來有一定規則可循
  • UML 類別圖內使用空心的箭頭來代表繼承(Inheritance)
  • Java 藉由 extends 關鍵字來表示繼承
  • 繼承是 is-a 或是 is-a-kind-of 的關係, 也就是子類別可以當作父類別的型別來看待
  • 繼承為了
    • reuse (共享程式)
    • 高度的擴充性


*單一繼承
  • 當一個類別只能繼承一個父類別, 這種限制稱為單一繼承 ( single inheritance)
  • Java 是單一繼承的語言
  • Java 透過介面(Interface)提供多重繼承的優點, 也避開多重繼承的缺點

*多重繼承的缺點
  • 如果帶有相同方法簽章的方法, 無從判別該呼叫那一個方法

*存取控制
  • private
    • UML表示為 -
    • 只有類別自己才可存取(same class)
  • default
    • UML表示為 ~
    • 相同套件也可以存取, 預設的存取控制(same package)
  • protected
    • UML表示為 #
    • 除了相同套件也可以存取, 開放到其他套件的子類別(有繼承該套件)(subclass)
  • public
    • UML表示為 +
    • 完全公開(universal)

*存取修飾子適用對象
  • 類別只有 default 或是 public 兩種

Lab: 觀察 Access Control

A.java

package xxx; //隸屬於 xxx 套件

public class A {

private int foo = 500;
//這邊我分別用四種不同的 access control 來讓之後的套件看是否可以存取的到
private void privatePlay() {
System.out.println("A private playing");
}

void defaultPlay() { //不寫任何 access control 就是 default
System.out.println("A private playing");
}

protected void protectedPlay() {
System.out.println("A private playing");
}
public void publicPlay() {
System.out.println("A private playing");
}

}


B.java

package xxx;

public class B {

public void mB() {
A x = new A();
// 使用 x. to see which access method can be use
}
}


C.Java

package yyy;

import xxx.A;

public class C extends A {

public void mC() {
A x = new A(); //No need to new
//use this. to see access control

// use super to access play() if set protected

}
}

D.java

package zzz;

import xxx.A;

public class D {

public void mD() {
A x = new A();
//use x. to see which access control can be use

}
}


*Overriding 方法
  • 子類別可以修改從父類別所繼承下來的行為
  • 子類別可以建立相同方法簽章(method signature),卻提供不同方法實作
    • 方法簽章(method signature)指的是
      • 方法名稱
      • 回傳型別
      • 參數傳遞列
  • Java 5.0 回傳型別可以是被Overriden 方法回傳型別的子類別

上述說明如下
有三各類別
Pet <---- Dog (Dog 繼承 Pet)
Pet <---- Cat (Cat 繼承 Pet)

public class Parent{
public Pet getFavorite(){}
}

public class Child extends Parent{
public Cat getFavorite(){} //可以寫成 Cat 或是 Dog, 不一定要寫成 Pet, 任一型別都可以
}


*呼叫被Overriden的方法
  • super 關鍵字可以用來參考父類別的成員, 包括父類別的屬性及方法.
  • 透過super呼叫的方法未必直接定義在父類別, 他可以定義在更上層的類別.

Notes:
  • Java 支援遞迴式的呼叫, 方法可以呼叫自己

*建構子不會被繼承

*呼叫父類別的建構子
  • 可以在建構子的第一行透過 super( )來呼叫父類別的建構子
  • super( ) 是呼叫父類別不帶參數的建構子
  • 一個建構子的this( ) 或是 super( ) 呼叫只能擇其一, 且必須出現在建構子有效程式的第一行
  • 一個建構子如果沒有使用 this 或是 super 的呼叫, compiler 會自動加上一個不帶參數的 super( ) 呼叫
  • 如果父類別定義一個以上的建構子, 但是沒有提供不帶參數的建構子, 而子類別沒有定義任何的建構子, 此時子類別會被建立一個 super( ), 會去呼叫父類別不帶參數的建構子, 此時會產生編譯錯誤

*this & super
  • this
    • this. 呼叫相同類別裡的成員
    • this( ) 呼叫相同類別裡的建構子
  • super
    • super. 呼叫父類別的成員
    • super( ) 呼叫父類別的建構子

Notes:
  • Java 內的唯二的隱含變數 this & super

沒有留言: