Java 處理錯誤的class都放在Error和Exception class下,而他們共同繼承Throwable class。
1.Error:是指無法控制或處理的錯誤狀況。如系統資源不足或網路斷線。因此可以不必處理這些問題。
2.Exception:可分為兩大類。一類為程式設計上的疏忽造成的RuntimeException,就算不處理也不會造成編譯失敗;另一類是Non-RumtimeException,又稱為CheckedException,如果沒有事先預防和處理,會造成編譯失敗。
2007/08/30
Bug
1.syntax error(語法錯誤):程式編譯時發現在的語法錯誤,compiler會告知錯誤行號,屬於較容易Debug的錯誤。Ex: int x = 1.0 ;
2.runtime error(執行時的錯誤):編譯時沒有發生錯誤,但是執行的時候發生錯誤。如整數除以0。
3.logic error(邏輯錯誤):程式在編譯跟執行時都沒有發生錯誤,但是結果卻不是使用者所想要的。此種錯誤是最難Debug的,必須要使用者的協助,否則程式設計師很難自己發現錯誤。
2.runtime error(執行時的錯誤):編譯時沒有發生錯誤,但是執行的時候發生錯誤。如整數除以0。
3.logic error(邏輯錯誤):程式在編譯跟執行時都沒有發生錯誤,但是結果卻不是使用者所想要的。此種錯誤是最難Debug的,必須要使用者的協助,否則程式設計師很難自己發現錯誤。
2007/08/15
Constructor
1.預設建構式(Default Constructor):沒有參數,屬性的初始值使用預設值。
2.非預設建構式(Non-default Constructor):有參數,屬性的初始值使用傳進來的參數設定。
Rules:
1.無傳回值設定:Constructor主要目的在於設定屬性(field)初始值,因此不需要傳回值設定,也不需要在建構式前加上『void』,否則compile error。
2.名稱要與類別相同:如果類別名稱是painter,其建構式的名稱也必須為painter。
class Painter{
String name;
public Painter(){//default constructor
name = "小畫家";
}
public Painter(String n){//non-default constructor
name = n;
}
public static void main(String args[]){
Painter paint = new Painter();
Painter paint2 = new Painter("畫圖");
}
}
2.非預設建構式(Non-default Constructor):有參數,屬性的初始值使用傳進來的參數設定。
Rules:
1.無傳回值設定:Constructor主要目的在於設定屬性(field)初始值,因此不需要傳回值設定,也不需要在建構式前加上『void』,否則compile error。
2.名稱要與類別相同:如果類別名稱是painter,其建構式的名稱也必須為painter。
class Painter{
String name;
public Painter(){//default constructor
name = "小畫家";
}
public Painter(String n){//non-default constructor
name = n;
}
public static void main(String args[]){
Painter paint = new Painter();
Painter paint2 = new Painter("畫圖");
}
}
2007/08/14
Multi-Inheritance
(1) class僅可繼承(extends) 1個class
(2) class可實作(implements)多個interface
(3) class不可繼承interface
(4) interface可繼承多個interface
(5) interface不可繼承classinterface不可實作interface
(2) class可實作(implements)多個interface
(3) class不可繼承interface
(4) interface可繼承多個interface
(5) interface不可繼承classinterface不可實作interface
Interface
1.interface的field一定要初始化,因為編譯時會自動加上final。
2.因為interface的field一定要初始化,所以interface沒有constructor。
3.interface只可以有abstract method。
4.interface的method無論有沒有加abstract都是abstract method。
5.無法使用new產生instance。
6.其sub class需implement(實作)所有method內容;但sub interface則不用。
2.因為interface的field一定要初始化,所以interface沒有constructor。
3.interface只可以有abstract method。
4.interface的method無論有沒有加abstract都是abstract method。
5.無法使用new產生instance。
6.其sub class需implement(實作)所有method內容;但sub interface則不用。
Abstract Class
1.抽象類別無法使用[new]運算符號來產生實體(instance)
2.一個class中只要有一個abstract method,整個class就必須宣告成abtract class[意味著可以寫有內容的method]
3.abstract class 的子類別必須把父類別中的所有抽象方法實作出來,所謂實作就是將大括號加上即可,裡面可以不寫任何程式碼
4.abstract class的子類別沒有把父類別的抽象方法實作出來或沒有全部實作,子類別也必須宣告為abstract class。
5.即使類別內沒有任何抽象方法,該類別也可被宣告為抽象類別,但較少見。
2.一個class中只要有一個abstract method,整個class就必須宣告成abtract class[意味著可以寫有內容的method]
3.abstract class 的子類別必須把父類別中的所有抽象方法實作出來,所謂實作就是將大括號加上即可,裡面可以不寫任何程式碼
4.abstract class的子類別沒有把父類別的抽象方法實作出來或沒有全部實作,子類別也必須宣告為abstract class。
5.即使類別內沒有任何抽象方法,該類別也可被宣告為抽象類別,但較少見。
Encapsulation
所謂Encapsulation(封裝)就是對屬性(field)設定成private,不讓其他人直接存取,以免無法檢查別人所設定的值,而提供set method和get method來讓其他人設定及取其值,而不至於讓別人可能輸入錯誤的值與破壞整個值。
Modifier
public 無限制( no limited )
protected 繼承( limited in inheritance )
default 套件( limited in package )[相同的目錄]
private 類別( limited in class )
protected 繼承( limited in inheritance )
default 套件( limited in package )[相同的目錄]
private 類別( limited in class )
2007/08/07
Shadow, Overloading, Overriding
shadow(遮蔽):
在繼承過程中,在sub class宣告和super class相同field的話就不會繼承super class的field而是使用自己的field,此種情形稱為shadow。
class Cube{
String name;
double length;
double width = 5;
double height;
double volume(){return length * width * height;}
}
class Building extends Cube{
double width = 10;
String material;
}
result:
當讀取Building.width時,會讀到10 而不是 5。
overloading(多載):
同一個class內,若有2個method符合下列2個規則即可稱為overloading。
1. method名稱一樣,否則只是2個不同的method,不能稱為overloading。
2. 傳入的argument個數或資料類型不一樣,JVM會依據個數或資料類型來決定呼叫哪個method。
double volume() {
return length * width * height;
}
double volume(Cube cube) //多載(overload)
{
return volume() + cube.volume();
}
overriding(改寫)[重要]:
overriding只發生在繼承。若有2個method符合下列4個規則即可稱為overriding。
1. method名稱一樣,否則只是2個不同的method。
class Cube{
public void show() {}
}
class Building extends Cube{
public void showA() {}
}//編譯成功,但不是Overriding
2. 傳入的argument個數或資料類型一樣,否則只能稱做overloading。
class Cube{
public void show() {}
}
class Building extends Cube{
public void show(int i) {}
}//編譯成功,但不是Overriding,只能叫做Overload
3. return value的資料類型要一樣。
class Cube{
public void show() {}
}
class Building extends Cube{
public double show() {return;}
}//編譯失敗
4. sub class的access modifier(開放修飾詞)要大於或等於super class (大小依序為:public>protected>default>private)。
class Cube{
public void show() {}
}
class Building extends Cube{
protected void show() {}
}//編譯失敗
final修飾的method不能被改寫。static修飾的method只能被static method改寫,non-static method只能被non-static method改寫。
class Cube{
final public void show() {}
}
class Building extends Cube{
public void show() {}
}//編譯失敗
class Cube{
public void show() {}
}class Building extends Cube{
final public void show() {}
}//編譯成功,沒有錯誤
class Cube{
static public void show() {}
}
class Building extends Cube{
public void show() {}
}//編譯失敗
class Cube{
public void show() {}
}
class Building extends Cube{
static public void show() {}
}//編譯失敗
class Cube{
static public void show() {}
}
class Building extends Cube{
static public void show() {}
}//編譯成功
Overriding:
class Cube{
String name;
double length, width, height;
public void show() {
System.out.println("立方體名稱: " + name);
System.out.println("長 = " + length);
System.out.println("寬 = " + width);
System.out.println("高 = " + height);
}
}
class Building extends Cube{
String material;
public void show() {
System.out.println("建築物名稱: " + name);
System.out.println("長 = " + length);
System.out.println("寬 = " + width);
System.out.println("高 = " + height);
System.out.println("材質 = " + material);
}
}
在繼承過程中,在sub class宣告和super class相同field的話就不會繼承super class的field而是使用自己的field,此種情形稱為shadow。
class Cube{
String name;
double length;
double width = 5;
double height;
double volume(){return length * width * height;}
}
class Building extends Cube{
double width = 10;
String material;
}
result:
當讀取Building.width時,會讀到10 而不是 5。
overloading(多載):
同一個class內,若有2個method符合下列2個規則即可稱為overloading。
1. method名稱一樣,否則只是2個不同的method,不能稱為overloading。
2. 傳入的argument個數或資料類型不一樣,JVM會依據個數或資料類型來決定呼叫哪個method。
double volume() {
return length * width * height;
}
double volume(Cube cube) //多載(overload)
{
return volume() + cube.volume();
}
overriding(改寫)[重要]:
overriding只發生在繼承。若有2個method符合下列4個規則即可稱為overriding。
1. method名稱一樣,否則只是2個不同的method。
class Cube{
public void show() {}
}
class Building extends Cube{
public void showA() {}
}//編譯成功,但不是Overriding
2. 傳入的argument個數或資料類型一樣,否則只能稱做overloading。
class Cube{
public void show() {}
}
class Building extends Cube{
public void show(int i) {}
}//編譯成功,但不是Overriding,只能叫做Overload
3. return value的資料類型要一樣。
class Cube{
public void show() {}
}
class Building extends Cube{
public double show() {return;}
}//編譯失敗
4. sub class的access modifier(開放修飾詞)要大於或等於super class (大小依序為:public>protected>default>private)。
class Cube{
public void show() {}
}
class Building extends Cube{
protected void show() {}
}//編譯失敗
final修飾的method不能被改寫。static修飾的method只能被static method改寫,non-static method只能被non-static method改寫。
class Cube{
final public void show() {}
}
class Building extends Cube{
public void show() {}
}//編譯失敗
class Cube{
public void show() {}
}class Building extends Cube{
final public void show() {}
}//編譯成功,沒有錯誤
class Cube{
static public void show() {}
}
class Building extends Cube{
public void show() {}
}//編譯失敗
class Cube{
public void show() {}
}
class Building extends Cube{
static public void show() {}
}//編譯失敗
class Cube{
static public void show() {}
}
class Building extends Cube{
static public void show() {}
}//編譯成功
Overriding:
class Cube{
String name;
double length, width, height;
public void show() {
System.out.println("立方體名稱: " + name);
System.out.println("長 = " + length);
System.out.println("寬 = " + width);
System.out.println("高 = " + height);
}
}
class Building extends Cube{
String material;
public void show() {
System.out.println("建築物名稱: " + name);
System.out.println("長 = " + length);
System.out.println("寬 = " + width);
System.out.println("高 = " + height);
System.out.println("材質 = " + material);
}
}
Varargs (Variable-length Argument Lists)參數列表
如果不確定會傳幾個argument給method,此時會利用array當作argument來傳遞;但array的宣告與值的指定都十分麻煩,因此JDK 5.0新增了Varargs功能來解決這個問題。其實Varargs就是使用array來儲存argument。(還是用陣列會比較方便) 範例請參看[Varargs.java]。
JDK 5.0
void attend( String… name ){} = void attend( String name[] name){}
String… name = String name[] ={ “ ” , ” ” } ;
(新增功能)(會考)
規定:
( 1 ) 同一個class不能存在同樣的方法,其中一個使用Varargs,其中一個使用陣列
Compiler會辨識為同一個方法
EX:
void attend ( String… name ){}
void attend ( String name[] ){}
( 2 ) 如果方法要傳送不只一個參數,使用Varargs的參數需擺在最後面
EX:
void attend ( String… name , int i ) // 錯誤(編譯失敗)
void attend ( String name[] , int i ) // 正確
void attend ( int i , String… name ) // 正確
( 3 ) 同一個方法只能使用一個Varargs參數
EX:
void attend ( String… name , String… ID ) // 錯誤(編譯失敗)
void attend ( String… name ) // 正確
void attend ( String… ID ) // 正確
JDK 5.0
void attend( String… name ){} = void attend( String name[] name){}
String… name = String name[] ={ “ ” , ” ” } ;
(新增功能)(會考)
規定:
( 1 ) 同一個class不能存在同樣的方法,其中一個使用Varargs,其中一個使用陣列
Compiler會辨識為同一個方法
EX:
void attend ( String… name ){}
void attend ( String name[] ){}
( 2 ) 如果方法要傳送不只一個參數,使用Varargs的參數需擺在最後面
EX:
void attend ( String… name , int i ) // 錯誤(編譯失敗)
void attend ( String name[] , int i ) // 正確
void attend ( int i , String… name ) // 正確
( 3 ) 同一個方法只能使用一個Varargs參數
EX:
void attend ( String… name , String… ID ) // 錯誤(編譯失敗)
void attend ( String… name ) // 正確
void attend ( String… ID ) // 正確
method
在method的block內有許多程式碼,當method被呼叫的時候,這些程式碼就會被執行method如果有return value(回傳值)則須在method名稱前加上return value的資料類型。即使method沒有return value,也須在method名稱前加上void。範例如下
[Method_ReturnValue.java]
class Cube {
String name;
double length;
double width;
double height;
double volume() {
return length * width * height;
}
}
class Method_ReturnValue{
public static void main(String argv[]) {
Cube box1 = new Cube();
box1.name = "1號箱子";
box1.length = 5.0;
box1.width = 3.0;
box1.height = 2.0;
if(box1.volume() <= 50)
System.out.println("空間足夠");
else
System.out.println("空間不夠");
}
}
method可以設定argument(參數)以處理更複雜的情況,範例如下
[Method_Argument.java]
class Cube{
String name;
double length;
double width;
double height;
double volume() {
return length * width * height;
}
double volume(Cube cube) //多載(overload) {
return volume() + cube.volume();
}
}
class Method_Argument{
public static void main(String argv[]) {
Cube box1 = new Cube();
box1.name = "1號箱子";
box1.length = 5.0;
box1.width = 3.0;
box1.height = 2.0;
Cube box2 = new Cube();
box2.name = "2號箱子";
box2.length = 6.0;
box2.width = 3.0;
box2.height = 2.0;
System.out.println("總體積為" + box1.volume(box2));
}
}
但要注意所傳的argument是屬於primitive type還是reference,範例如下
[ArgumentPass.java]
class ArgumentPass{
public void update(int i){i++;}
public void update(int x[]){x[0]++;}
public static void main(String args[]) {
ArgumentPass arg = new ArgumentPass();
int j = 1;
int y[] = {1,2,3};
arg.update(j);
arg.update(y);
System.out.println(j);
System.out.println(y[0]);
}
}
result:
1
2
primitive type 屬於call by value, 而 Array 則屬與reference type,是call by reference。
[Method_ReturnValue.java]
class Cube {
String name;
double length;
double width;
double height;
double volume() {
return length * width * height;
}
}
class Method_ReturnValue{
public static void main(String argv[]) {
Cube box1 = new Cube();
box1.name = "1號箱子";
box1.length = 5.0;
box1.width = 3.0;
box1.height = 2.0;
if(box1.volume() <= 50)
System.out.println("空間足夠");
else
System.out.println("空間不夠");
}
}
method可以設定argument(參數)以處理更複雜的情況,範例如下
[Method_Argument.java]
class Cube{
String name;
double length;
double width;
double height;
double volume() {
return length * width * height;
}
double volume(Cube cube) //多載(overload) {
return volume() + cube.volume();
}
}
class Method_Argument{
public static void main(String argv[]) {
Cube box1 = new Cube();
box1.name = "1號箱子";
box1.length = 5.0;
box1.width = 3.0;
box1.height = 2.0;
Cube box2 = new Cube();
box2.name = "2號箱子";
box2.length = 6.0;
box2.width = 3.0;
box2.height = 2.0;
System.out.println("總體積為" + box1.volume(box2));
}
}
但要注意所傳的argument是屬於primitive type還是reference,範例如下
[ArgumentPass.java]
class ArgumentPass{
public void update(int i){i++;}
public void update(int x[]){x[0]++;}
public static void main(String args[]) {
ArgumentPass arg = new ArgumentPass();
int j = 1;
int y[] = {1,2,3};
arg.update(j);
arg.update(y);
System.out.println(j);
System.out.println(y[0]);
}
}
result:
1
2
primitive type 屬於call by value, 而 Array 則屬與reference type,是call by reference。
OOP物件導向程式設計
人類生活中所需處理的問題,單靠primitive type無法完整描述。因此我們需要OOP(Object-Oriented Programming),程式設計師可以自訂類別,稱作class。
class cube{
double length;
double hieght;
double width;
}
class可以說是一個泛稱,而object便是class的實體。例如”我的箱子”屬於立方體,因此可以說我的箱子是Cube class的一個object。一個java檔案中可以有好幾個class,但只有一個class前面可以加public修飾詞(modifier),而且有public修飾的class名稱必須亦為檔案名稱。由於[BoxFactory.java]中的public class名稱為[BoxFactory],因此檔案名稱必須為[BoxFactory.java]。範例[BoxFactory.java]中的Cube class與BoxFactory class可以寫在同一個java檔案內,也可以分開寫在2個java檔案內以利於專案分工;但不論如何,編譯後都會產生2個[.class]檔案。
class cube{
double length;
double hieght;
double width;
}
class可以說是一個泛稱,而object便是class的實體。例如”我的箱子”屬於立方體,因此可以說我的箱子是Cube class的一個object。一個java檔案中可以有好幾個class,但只有一個class前面可以加public修飾詞(modifier),而且有public修飾的class名稱必須亦為檔案名稱。由於[BoxFactory.java]中的public class名稱為[BoxFactory],因此檔案名稱必須為[BoxFactory.java]。範例[BoxFactory.java]中的Cube class與BoxFactory class可以寫在同一個java檔案內,也可以分開寫在2個java檔案內以利於專案分工;但不論如何,編譯後都會產生2個[.class]檔案。
2007/08/02
Array copy and assign
Array assign:
int em01[] = {35000, 32000, 35000, 28000, 30000};
int em02[] = em01;
em01[0] = 25000;
System.out.println("em01[0] = " + em01[0]);
System.out.println("em02[0] = " + em02[0]);
result:
em01[0] = 25000
em02[0] = 25000
Array 在assign的時候,是將記憶體位址指定到em02,所以em01和em02是用同一個記憶體位址,也就是同一個變數
Array copy:
int em01[] = {35000, 32000, 35000, 28000, 30000};
int em02[] = new int[em01.length];
System.arraycopy(em01, 0, em02, 0, em01.length);
em01[0] = 25000;
System.out.println("em01[0] = " + em01[0]);
System.out.println("em02[0] = " + em02[0]);
result:
em01[0] = 25000
em02[0] = 35000
Array在copy的時候,須先宣告一個新的陣列,運用函式庫arraycopy,傳值給em02,因此兩個是屬於不同個變數,因此其中一個改變值的時候,另外一個不會一起改變。另外,不一定要用函式庫才能copy,當然也可以自己寫成是一個一個指定值。
int em01[] = {35000, 32000, 35000, 28000, 30000};
int em02[] = em01;
em01[0] = 25000;
System.out.println("em01[0] = " + em01[0]);
System.out.println("em02[0] = " + em02[0]);
result:
em01[0] = 25000
em02[0] = 25000
Array 在assign的時候,是將記憶體位址指定到em02,所以em01和em02是用同一個記憶體位址,也就是同一個變數
Array copy:
int em01[] = {35000, 32000, 35000, 28000, 30000};
int em02[] = new int[em01.length];
System.arraycopy(em01, 0, em02, 0, em01.length);
em01[0] = 25000;
System.out.println("em01[0] = " + em01[0]);
System.out.println("em02[0] = " + em02[0]);
result:
em01[0] = 25000
em02[0] = 35000
Array在copy的時候,須先宣告一個新的陣列,運用函式庫arraycopy,傳值給em02,因此兩個是屬於不同個變數,因此其中一個改變值的時候,另外一個不會一起改變。另外,不一定要用函式庫才能copy,當然也可以自己寫成是一個一個指定值。
訂閱:
文章 (Atom)