想要找 Java 教材:
http://programming.im.ncnu.edu.tw/J_index.html
1. function 一定要明確 "指出" 回傳值 void int... JAVA 很在意這個
--
public class myExcep
{
public static void main(String args[])
{
java.util.Scanner sc = new java.util.Scanner(System.in);
int num = sc.nextInt(); /* 當輸入不是 int 時,會出現 exception */
System.out.println(x); /* java.util.InputMismatchException */
}
}
--
switch (grade)
{
case 'A':
System.out.println("ok");
break;
case 'B':
break;
}
--
陣列在存取時超出範圍,會發生例外狀況
Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10
如果存取一個並未配置空間的陣列參考,會出現
Exception in thread "main" java.lang.NullPointerException
--
Call by Value: 基本型別 (int, float, String...)
Call by Reference: 陣列、物件
foo (int tmp[][]) { do something ... }
bar {
int num[][] ={ {1,2}, {3,4} }
foo (num); /* 這邊是call by reference,所以把參照 num 值拷了一份給 tmp*/
}
--
類別方法(Class Methods)
就是用 static 描述的方法,不用生出物件也可以直接呼叫
class myExample
{ public static void showName()
{ System.out.print("name: Peter");
}
}
類別變數(Class Variables)
成員變數屬於類別本身,當類別第一次建立時,就配置變數的記憶體
class myExample
{
public static double PI=3.1415;
public static int count=0;
myExample() { count++; }
}
main ()
{
myEx obj[] = new myEx[2];
obj[0] = new myEx();
obj[1] = new myEx();
System.out.println( obj[0].count ); /* 會得到 2 */
}
--
函式在多載,主要是用 input 的參數型別、個數來當識別,例如像:
public static void show(int x) 兩者視為相同,無法分辨
public static double show(int x) 因為皆是傳入一個 int 參數。
--
數學函式的用法,直接用 Math.FUNCTION() 來呼叫就可以,不用 import 其他類別庫,
例如:
Math.max(12, 37) // 取大值
Math.round(12.32) // 四捨五入
重要的是 Math 類別提供了兩個 static 變數
Math.PI
Math.E
另外 Math 也提供了亂數可供使用
Math.random(); // 產生 0.0 ~ 0.9999999 的亂數
Math.random() * 100 // 產生 0.0 ~ 99.9999999(無窮小數)
--
陣列的宣告法
int [] data = {1,2,3,4,5};
int [][] data = { {1,2,3} , {4,5} , {29,3,2,4,5} };
int [] data = new int [] {1,2,3,4,5};
底下這個方式很特別,稍微學一下。其中 Float 是一種物件
Object data[] = new Object[] {new Integer(28), new Float(12.1)};
/* 把 [][] 看成雙重指標 所以千萬不可以寫成 new int[10] */
/* 否則會出現 incompatible types found : int[] required: int[][] */
int [][] num = new int[10][];
num[0] = new int[(int) (Math.random()* 10) ];
--
陣列你要想成,有多個指標幫你指向物件,
class node { public int data; }
在用的時候,千萬記住要各別 new 出物件來
node myNode[] = new node[5];
myNode[0] = new node(); /* 各別再去配置空間 */
myNode[0].data = 10;
System.out.println(myNode[0].data);
同理也用在 Double 物件上面
Double foo1[] = new Double[5];
foo1[0] = new Double(5);
System.out.println(foo1[0]);
但是如果是基本型別的資料,就可以直接用
double foo2[] = new double[5];
foo2[0] =5;
System.out.println(foo2[0]);
--
String 是種物件,用法
String tmp = new String("the_key_word");
System.out.println( tmp.indexOf("key") ); /* 找出 key 這個字第一次出現*/
String num="123";
Integer.parseInt(str);
--
建構元的名稱,要與類別名稱相同
class Circle
{
public Circle() /* 修飾子可為 public 表示外界能呼叫 */
{ this(19); } /* 用 this 這個關鍵字來呼叫建構元 */
private Circle(int x) /* 若為 private 則是只能透過內部呼叫 */
{ System.out.println(x); }
}
--
兒子的 Constructor 如果有呼叫到父親的 Constructor,則要放在第一行
而且是用 super 這個關鍵字。
class Student extends Person
{
Student()
{ /* 呼叫父親的建構子, should be at the 1st line */
super();
System.out.println("Student() ");
}
void foo() { System.out.println("Son foo"); }
void bar() { super.foo(); } /* 自己也有 foo() 所以
如果要呼叫老爸的 foo() 就用 super 這字 */
}
--
super 的用法有兩種:
1. 用來呼叫父類別建構子: super();
用來呼叫父類別特定的建構子: super(27, "abc");
2. 用來呼叫父類別的函式:如果父親、兒子都有 foo() ,
要特定指名呼叫 父的foo() 就用super.foo()
class CBase { protected int value=10; } /* protected 允許讓兒子繼承 */
class CExt mextends CBase
{
public int value=20; /* 此時 CExt 會有兩個 value:自身、由父類來的 */
public int get_Value() { return (value); }
public void set_Value(int x) { value = x; }
public int get_Base_Value() { return (super.value); }
public void set_Base_Value(int x) { super.value = x;}
}
public static void main(String args[])
{
CExt obj1 = new CExt(); obj1.set_Base_Value(28);
CExt obj2 = new CExt(); obj2.set_Base_Value(99);
System.out.println( obj1.get_Base_Value() ); /* 得到 28 */
System.out.println( obj2.get_Base_Value() ); /* 得到 99 */
}
--
this 的用法還有另一招
(注意:在 C++ 語言中,this 是一個指標,所使用時要用 -> 來操作)
class CBase
{
public int value=10;
public void show()
{ int value=99;
System.out.println (this.value); /* 物件成員 10 */
System.out.println (value); /* 區域變數 99 */
}
--
關於 final 的用法
1. 禁止 function 被子類別改寫(overriding)
class Base { public final void show() {...} }
/* 錯誤!! overridden method is final */
class Ext extends Base { public void show() {...} } /* 不允許自己重新定義 */
2. 用來達到 常數(constant) 的作用
class Base { public static final double pi=3.14; }
class Ext extends Base {
double pi=8; ○ /* 自己可以另外搞一套 */
show() { super.pi=10; ╳ } /* 但是不可修改到父類那組 */
show() { pi = 10; }
}
3. 禁止 class 被繼承
final class Base {}
class CExt extends CBase /* cannot inherit from final CBase */
--
問題:
1. 我在 myExcep.java 中用到 myClass.Java 的類別變數
為什麼 myClass.java 在每次重新執行時,不需要重新編譯?
2. Math.random() 到底產生的範圍是什麼? 去確認一下
類別 java.util.Random 又是怎樣
3. String.indexOf() 的用法到底怎樣
--
開始談 class 的用法
class FOO()
{
private int num=0; /* private 變數隻允許自己的類別來存取 */
public set_Num(int x) { num = x; }
}
public class myEx
{
public static void main(String args[])
{ FOO obj = new FOO();
FOO.num=10; ╳
FOO.set_Num(10); ○
}
}
--
在一個建構子中,要呼叫另一個建構子時,用的是 this
而且 this 關鍵字 只能放在建構元內的第一行。
class Cfoo
{ String name;
Cfoo()
{ this("default"); } /* this.Cfoo("default") 這是錯的用法 */
Cfoo(String x)
{ name = x ; }
}
--
預設的建構子
class Cfoo {} 的預設建構子會長成: public Cfoo()
--
在類別函式中,不可以呼叫 實例函式/實體變數,因為這些東西屬於個別物件所有
non-static method my() cannot be referenced from a static context
class Cfoo
{
static int num=0;
int age;
public void my() { }
static void my_s() /* (╳) 類別函式 不可以呼叫 實例函數、實例變數 */
{ my(); }
}
在類別函式中,也不能使用 this這個關鍵字,因為 this 是指呼叫該 method 的物件。
class Cfoo
{ int num=0; /* 物件變數 */
public static void get_Num() /* 類別函式 (!!不可以用到物件變數!!) */
{
System.out.println ( num ); /* 這也是不允許的 ,沒物件跟本不會有 num*/
System.out.println ( this.num ) /* this 代表呼叫這個函式的物件 */
} /* 不允許 */
}
--
class complex
{
double a,b;
public boolean compre(complex obj)
{ /* 要用每個欄位下去逐一比對 */
if ( this.a==obj.a && this.b==obj.b) return true;
else return false; /* 如果寫成 this==obj 這表示,比較兩指標所指位置 */
}
}
--
在 obj 物件內改寫 toString() 函式,注意看這邊的語法,奧義。
public static void main(String args[])
{
Object obj = new Object()
{
public String toString() /* 改寫 fucntion */
{ return ("noname"); }
};
System.out.println( obj.toString() );
}
--
繼承登場
父類別 子類別
====== ======
沒有宣告 public/private ----> 沒有宣告 public/private
public 成員 ----> 一樣是 public
private 成員 ----> 只能透過父類別的函式來存取
建構元 ----> 不能繼承
class Circle
{ public Circle() {System.out.println("Circle constructor()");}
public Circle(int x) {System.out.println("Circle constructor(int x)");}
}
class Coin extends Circle
{ /* 什麼都沒寫,預設會去呼叫父類別的 Circle() - 即 super() */
public Coin() { System.out.println("Coin construcotr()"); } 與下面同樣意思
public Coin() { super(); System.out.println("Coin construcotr()"); }
/* 如果想要 呼叫特定的 父類別建子,那就用 super() - 會呼叫 Circle(int x) */
public Coin(int x) { super(x); System.out.println("Coin construcotr()"); }
}
--
書本上有談到 overriding 與 overloading
overriding - 在子類別中,定義名稱、引數個數、傳回值型態均與父類別相同的method
overloading - 在相同類別中,定義名稱相同,引數數目不同,或者型態不同的method
--
抽象類別登場 (子類別用 extends 來繼承,再補齊原本 abstract 部份)
所謂抽象類別就是內含有 abstract function 的類別。其使用語法如下:
abstract class Shape /* 別忘了 class 要加上宣告 abstract */
{ public abstract void show(); } /* 然後當然也少不了 函式的部份 */
class Rectangle extends Shape /* 定義 Rectangle 之後準備實作 show() */
{ public void show() { System.out.println ("Rect()"); } }
class Circle extends Shape /* 定義 Circle 之後實作 show() */
{ public void show(){ System.out.println ("Circle()"); } }
1. 抽象類別(abstract class)不可用來產生物件
2. 在抽象類別中所有 "抽象函數" 必定要在子類別中實作,這樣才可用子類別建物件
(別忘了,只要有一個抽象函數存在,該 class 就變成 abstract class
abstract class 是不能用來產生物件的。)
3. 抽象類別中,可以有部份函數已經實作。未實作部份就是由子類別來補齊。
4. 一個抽象函數,可以宣告為 public/protected
--
談談 interface
1. 介面中的成員變數,要設定初值
2. 在介面中的 function 默認都是 abstract 了
在介面中的 成員變數 默認都是 final 了,不能更改其值 (一開始就要給初值)
3. 成員函數只能宣告為 public 或者不宣告。不能宣告為 protected/private。
4. 在實作 function 時,傳數參數的型別、數目,與回傳值 都要與介面定義內的相符合。
5. 所有在介面內定義的 function 都要在類別(class) 中實作出來,
否則該類別就變成 abstract class
interface Shape
{
int value=10;
public abstract void foo();
public abstract void bar();
}
abstract class Circle implements Shape /* 抽象 - 因為 bar() 沒有實作出來 */
{
public void foo() { System.out.println("hello"); }
}
class Triangle implements Shape /* 全部的函式都實作完,可以用來建立物件 */
{
public void foo() {...}
public void bar() {...}
}
--
在 java 中並不支援使用 extends 來多重繼承,而是用 "介面" implements 來實現
interface Shape { public abstract void show(); } /* 傳入參數要給名字 */
interface Color { public abstract void setColor(String x); }
class Circle implements Shape, Color
{ public void show() {...} /* 所有 函式 都要實作,否則會變成抽象類別*/
public void setColor(String x) {...}
}
--
討論 interface 與 abstract 的差別
1. 介面內的 變數成員,要設定為常數
介面內的 所有方法,都設定為抽象方法。
2. 抽象類別允許:變數不需要設定初值 + 一般函數/抽象函數 並存。
- Feb 05 Sat 2011 22:42
Java 速成
全站熱搜
留言列表