星期一, 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

VMware Player 5 小記

這個學期的教學講座會有比較多的實作 -- 但是電腦教室一般都有還原卡的設計

正在測試 VMware Player 5.0.0
http://www.vmware.com/products/player/overview.html
這個版本比上個版本感覺更 smooth, 也不用重開機

目前實驗設定 vmnetcfg.exe 是否可以

1. 自訂網段


目前VMware Player 5 內的 vmnetcfg.exe 被拿掉了, vmnetcfg.exe 被放在VMware Workstation 9 內, 解決方案的方法是下載 VMware Workstation 9
假設下載的檔案是 VMware-workstation-full-9.0.0-812388.exe
在命令提示字元下以下指令
VMware-workstation-full-9.0.0-812388.exe   /e    .\work9exarct


  • /e 代表解壓縮
  • .\work9exarct  為解壓縮後的目錄名稱, 可以自訂
這個時候就會看到有個 work9exarct 的目錄
開啟目錄內的 core.cab 檔案, 就會發現有 vmnetcfg.exe
將他複製到 VMware Player 目錄 (  C:\Program Files\VMware\VMware Player ) 內
就可以指定網段的範圍了


2. 更改 HotKeys
(按Ctrl + Alt + Shift 才跳出 Guest, 不會跟 Linux 的 Ctrl + Alt 衝突)


 
修改 HotKeys 的部分目前沒有改變 

For Windows XP
C:\Documents and Settings\使用者帳號\Application Data\VMware\preferences.ini

For Windows 7
C:\Users\使用者帳號\AppData\Roaming\VMware\preferences.ini

請加入 pref.hotkey.shift = "true"

將 VMware Player 關掉重開即可生效





看來之後都是使用 VMware vSphere Hypervisor (Esxi ) 5 以及 VMware Player 了
已經很久沒有用到 VMware Server 了
但是還是希望 VMware Fusion 可以有 Link Clone 的功能

enjoy it ~~

星期三, 10月 03, 2012

OCPJP Day 6


Lab: 判斷奇數還是偶數

新增一個 IfEvenOrOdd 的類別

package mod07;

public class IfEvenOrOdd {
public static void main(String[] args){
int num = Integer.parseInt(args[0]);
if(num%2 == 0) //判斷除以2後的餘數是否等於 0
{
System.out.println(num+" is 偶數");
}
else
{
System.out.println(num+" is 奇數");
}
}
}

Notes:
  • 這邊有注意到 Netbeans 會把編譯後的class放在專案目錄下的 build/clesses 資料夾, 所以如果要執行這個範例就要在 clesses 資料夾下 java mod07/IfEvenOrOdd 111


*for迴圈
  • 常用在次數確定的迴圈, 是一種 0 到多的迴圈
  • 語法: for( [初始化] ; [條件式] ; [後處理] )
    • 以 ; 為分隔符號
    • 初始化只會執行一次
    • 如果滿足條件式就會進行後處理

Lab: for 迴圈

package mod07;

public class TestForLoop {

public static void main(String[] args) {
int i = 0; //為了證明 for 迴圈的初始化是optional 還有想要知道 I 在第幾個值跳出來, 在這邊宣告
for ( ; i < 10; i++) { //第一個欄位沒有填
System.out.println("Hello"+i);
}
System.out.println("i = "+i); //列出 i 的值
}
}

Notes:
  • 可以藉由去修改專案的屬性 (File → Project Properties 內的 Run) 去填入不同的arguments, 這樣就未必一定要到終端機下去下引數.


*while 迴圈
  • 迴圈次數不確定時常用的方式, 是一種 0 到多的迴圈
  • 語法 while ( boolean 運算式 ) { }

Lab: while

package mod07;

public class TestWhileLoop {

public static void main(String[] args) {
// TODO code application logic here
int i = 0;
while (i < 10){
System.out.println("Hello "+ i);
i++;
}
System.out.println("i = "+i);
}
}

– Take Break 15 mins –

*do … while 迴圈
  • 無論如何會執行一次, 1 到多的迴圈
  • 語法 do { } while (boolean 運算式);
    • 記得結束要有 ; 分號


Lab: do … while

package mod07;

public class TestDoWhileLoop {

public static void main(String[] args) {
int i = 0; //宣告 i = 0 初始化
do{
//至少會執行一次 at least run one time
System.out.println("Hello "+i);
i++;
}while(i < 10); //i 小於10 就執行
System.out.println("i = "+i);
}
}



*break, continue, label
  • 控制迴圈的手段
  • break 終止迴圈的執行
  • continue暫停目前的迴圈, 提早進入下一個迴圈的判斷式


說明 break
do{
statement1;
if (a > 10){
break; // 因為是 break 所以會終止目前的迴圈, 跳到 statement 3
}
statement2;
} while ( b > 10 );
statement3;

說明 continue

do{
statement1;
if (a > 10){
continue; //因為是 continue, 所以會繼續下一回合的邏輯判斷 while(b > 10)
}
statement2;
} while ( b > 10 );
statement3;

說明 label

outer: //這個是 label
do{
statement1;
do{
statement2;
if(a > 10) {
break Outer; //指定 break Outer 所以跳出 Outer , 執行 statement 5
}
statement3;
} while (b > 10);
statement4;
} while ( c > 10);
statement 5;

說明 label

outer: //這個是 label
do{
statement1;
do{
statement2;
if(a > 10) {
continue Outer; //指定 continue Outer 執行 Outer 判斷 while( c> 10)
}
statement3;
} while (b > 10);
statement4;
} while ( c > 10);
statement 5;


Lab: 九九乘法表

package mod07;

public class ForMultiTable {

public static void main(String[] args) {
for( int i = 1; i <= 9; i++){
for(int j=1; j <= 9; j++){
System.out.print(i+"*"+j+"="+(i*j)+"\t"); //若要排列整齊, 使用 tab的方式
}
System.out.println();
}
// for 三角形列出
for( int i = 1; i <= 9; i++){
for(int j=1; j <= i; j++){
System.out.print(i+"*"+j+"="+((i*j<10)?" ":"")+(i*j)=" "); //若要排列整齊另一種方式
}
System.out.println();
}
}
}



*Chapter 8 封裝概論

Notes:
  • 藉由封裝來釐清責任歸屬

*存取物件的成員
  • 用點符號來存取
  • 這種方式可以用來存取物件的成員, 包含屬性和方法

*public 存取控制關鍵字
  • 類別圖的 + 代表 public
  • 表示該物件成員可由類別外部直接存取

Notes:
  • 如果使用屬性的方式來修改
    • 缺點:
      • 必須將資料驗證放在用戶端程式(client code)
      • 程式碼散落各用戶端程式
      • 程式碼可能不一致
      • 維護性大幅降低
  • 所以修改使用方法的方式比修改屬性來的好
    • 驗證程式碼統一集中於方法內
    • 方法內部可修改不同的實作而不影響用戶程式碼 (前提為: 方法簽章(方法名稱, 資料型別, 參數列)必須保持固定不變[操作存取介面])


*private 存取控制
  • 類別圖的 - 代表 public
  • 表示該物件成員只能由類別內部存取, 而不能由類別外部存取
  • 透過方法來存取物件屬性

*getter and setter 方法
  • 透過 getter 和 setter 方法來存取 private 屬性

*封裝
  • 將類別的實作細節(屬性, 方法內部的實作)隱藏起來
  • 迫使用戶端透過公開的介面來存取物件的資料