PIXNET Logo登入

Kalin的部落格

跳到主文

歡迎光臨Kalin在痞客邦的小天地

部落格全站分類:不設分類

  • 相簿
  • 部落格
  • 留言
  • 名片
  • 12月 13 週二 200512:10
  • My fxxking Beans


水! 被爛蘿菠說又臭又長的 beans, 在歷經 2 個 projects, 終於有點規模了, 
 
http://stuweb2.cmp.uea.ac.uk/a048683-jsp/beans_docs_kalin/
 
 
雖然還有很多 bugs, 但是孩是迫不及待地搶先推出 Beta 版.
 
 
 
ps: 原來在 MSN space, fxxking 是被禁止的字. 真是 Fxxking!
 
(繼續閱讀...)
文章標籤

Kalin 發表在 痞客邦 留言(3) 人氣(7)

  • 個人分類:Java
▲top
  • 10月 03 週一 200519:53
  • 重複運用Classes (Composition & Inheritance)

兩種方法可以重複運用Classes:
1. composition(複合): 在新的Class中產生既有的Class物件, 這種情形只是單純的重複運用既有程式碼的功能, 而非重複運用其形式.
2. inheritance(繼承): 讓新的Class成為既有Class的一類, 可以實際接收既有Class的形式, 並加入新碼.
 


 
Composition: 只要將object references 置於新的classes即是.
 
"vm不會為每個reference產生預設物件"是有意義的, 因為這麼做會在許多情況下造成不必要的負擔, 但是如果希望初始化這些references, 可以在3個地點進行:
 
1. 物件定義處. 這表示它們一定能在"constructor被呼叫前完成初始化動作".
2. 在constructor裡.
3. 在實際需要用到該物件的地方. 這種方式被稱為lazy initialization(緩式初始化), 這種做法可以降低額外負擔.
 
以下程式用了這三種作法:
 
//Constructor initialization with Composition
class Soap
{
 private String s;
 Soap()
 {
  System.out.println("Soap()");
  s = new String("Constructed");
 }
 /*********************************************************
 if declaring with this way: String toString(), it can't compile via vm
   
 toString() in Soap cannot override toString() in java.lang.Object;
 attempting to assign weaker access privileges; was public String toString()
    *********************************************************/
 public String toString()
 {
  return s;
 }
};
public class Bath
{
 //Initializing at point of definition:
 private String
  s1 = new String("Happy"),
  s2 = "Happy",
  s3,
  s4;
 Soap castille;
 int i;
 float toy;

 Bath()
 {
  System.out.println("Inside Bath()");
  //intialization with constructor
  s3 = new String("Joy");
  i = 47;
  toy = 3.14f;
  castille = new Soap();
 }
 void print()
 {
  //Delayed Initialization:
  if (s4 == null)
  {
   s4 = new String("Joy");
  }
  System.out.println("s1 = "+s1);
  System.out.println("s2 = "+s2);
  System.out.println("s3 = "+s3);
  System.out.println("s4 = "+s4);
  System.out.println("i = "+i);
  System.out.println("toy = "+toy);
  System.out.println("castille = "+castille);
 }
 public static void main(String[] args)
 {
  Bath b = new Bath();
  b.print();
 }
}
 

---------- java ----------
Inside Bath()
Soap()
s1 = Happy
s2 = Happy
s3 = Joy
s4 = Joy
i = 47
toy = 3.14
castille = Constructed
Normal Termination
輸出完成 (耗費 0 秒)。

 
 
Inheritance:
1. 繼承後, derived class 自動獲取了base class 的所有資料成員與成員函式.
2. 為了繼承著想, base class 一般原則是將所有資料成員宣告成private, 將所有函式成員宣告為public.
3. 實施繼承時, 不一定非得使用base class 函式不可, 也可將新的method 加置derived class.
4. 即使沒有明確指出要繼承某個class, 仍會繼承Java 標準根源類別Object.
 
//Inheritance syntax & properties
class Cleanser
{
 private String s = new String("Cleanser");
 
 public void append(String a)
 {
  s += a;
 }
 public void dilute()
 {
  append(" dilute()");
 }
 public void apply()
 {
  append(" apply()");
 }
 public void scrub()
 {
  append(" scrub()");
 }
 public void print()
 {
  System.out.println(s);
 }
 public static void main(String[] args)
 {
  Cleanser x = new Cleanser();
  x.dilute();
  x.apply();
  x.scrub();
  x.print();
 }
};
 
public class Detergent extends Cleanser
{
 //change a method:
 public void scrub()
 {
  append(" Detergent.scrub()");
  //call bass-class version:
  super.scrub();
 }

 //add method to the interface:
 public void foam()
 {
  append(" foam()");
 }
 //test the new class:
 public static void main(String[] args)
 {
  Detergent x = new Detergent();
  x.dilute();
  x.apply();
  x.scrub();
  x.foam();
  x.print();
  System.out.println("Testing base class");
  Cleanser.main(args);
 }
}
 
 
(Kalin's 讀後心得1)
cleanser (n) 清潔工(跟每天叫我起床的cleaner一樣); 清潔劑(在這篇紀錄裡面應該是指清潔劑)
di'lute (v) 稀釋; 沖淡; 減輕 (a)沖淡的; 褪了色的
scrub (v) 擦洗
de'terge (v) 洗淨
det'ergent (n) 清潔劑 (a)有清淨力的
foam (v) 起泡沫 (n)泡沫
 
 
 
base class 的初始化: 建構動作會由base class"往外"擴散, 所以base class會在derived class 建構式取用它之前, 先完成本身的初始化動作.
 
//Constructor calls during inheritance
class Art
{
 Art()
 {
  System.out.println("Art constructor");
 }
};

class Drawing extends Art
{
 Drawing()
 {
  System.out.println("Drawing constructor");
 }
};

public class Cartoon extends Drawing
{
 /*
 Cartoon ()
 {
  System.out.println("Cartoon constructor");
 }
 */

 public static void main(String[] args)
 {
  Cartoon x = new Cartoon();
 }
}

 
---------- java ----------
Art constructor
Drawing constructor
Normal Termination
輸出完成 (耗費 0 秒)。

 
由執行class Cartoon 的結果看來, 即使並未撰寫Cartoon()建構式, vm也會為我們合成一個default 建構式, 並在其中呼叫base class 的建構式.
 
帶有引數(arguments)的建構式: 如果base class不具備default建構式, 或者想呼叫帶有引數的base calss constructor, 便得運用關鍵字super, 並搭配適當的引數列. 而且必須是derived class建構式的第一件要做的事情, 否則vm會提醒錯誤發生: call to super must be first statement in constructor.
 
//Constructor calls during inheritance
class Art
{
 Art(int i)
 
{
  System.out.println("Art constructor : "+i);
 }
};
class Drawing extends Art
{
 Drawing(int i)
 {
  super(i);
  /**********************************************
  假如沒有super(i), 編譯時會出現一個錯誤:
  Art(int) in Art cannot be applied to ()
  **********************************************/
  System.out.println("Drawing constructor : "+i);
 }
};
public class Cartoon extends Drawing
{
 
 Cartoon ()
 {
  super(11);
  /**********************************************
  假如沒有super(1), 編譯時會出現一個錯誤:
        Cartoon.java:23: cannot resolve symbol
        symbol  : constructor Drawing ()
  **********************************************/
  System.out.println("Cartoon constructor");
 }
 
 public static void main(String[] args)
 {
  Cartoon x = new Cartoon();
 }
}
 
---------- java ----------
Art constructor : 11
Drawing constructor : 11
Cartoon constructor
Normal Termination
輸出完成 (耗費 0 秒)。

 
 
Reference : Thinking in Java
(繼續閱讀...)
文章標籤

Kalin 發表在 痞客邦 留言(0) 人氣(2,038)

  • 個人分類:Java
▲top
  • 9月 21 週三 200510:22
  • static & instance variable & base class


以下程式碼與說明擷取自 JavaWorld, 並加以改編 :
 
session 1)
 
資料成員有分 static/non-static。
instance variable => non-static field(field: data member)
class variable => static field

 




class Insect
{
    int x1=prt("static Insect.x1 initialized");
 
    int prt(String s)
    {
        System.out.println(s);
        return 47;
    }
}
 
public class Beetle extends Insect
{
    public static void main(String[] args)
    {
    }
}

---------- java ----------
Normal Termination
輸出完成 (耗費 0 秒)。


 
將 x1 跟 prt() 重新改寫為 static.
 
class Insect
{
    static int x1=prt("static Insect.x1 initialized");
 
    static int prt(String s)
    {
        System.out.println(s);
        return 47;
    }
}
 
public class Beetle extends Insect
{
    public static void main(String[] args)
    {
    }
}
---------- java ----------
static Insect.x1 initialized
Normal Termination
輸出完成 (耗費 0 秒)。

 
我們可以將資料成員宣告為static,被宣告為static的資料成員,它是屬於類別所擁有,而不是個別的物件,我們可以將static視為個別物件所擁有、共享的資料成員。
 
static資料與函式的作用之一,是提供公用類別函式,例如將數學常用常數或計算公式,以static宣告並撰寫,之後我們可以透過類別名稱來管理與取用這些函式,例如像Math.Exp、Math.Log()、Math.Sin()等等的static常數或函式等,事實上,像PI這個常數,在Math.PI就有定義,我們可以直接呼叫使用。
 
由於static成員是屬於類別而不是物件,所以當您呼叫static函式時,並不會傳入物件的位置參考,所以static函式中不會有this參考,由於沒有this參考,所以在Java的static函式成員中不允許使用非static成員,因為程式沒有this來參考至物件位址,也就無法辨別要存取哪一個物件的成員,事實上,如果您在static函式中使用非static資料成員,在編譯時就會出現以下的錯誤訊息:



1

non-static variable test cannot be referenced from a static context

或者是在static函式中呼叫非static函式,在編譯時就會出現以下的錯誤訊息:


1

non-static method showMe() cannot be referenced from a static context

如果以c++來說 就是固定一個記憶體位置給宣告成 static 的成員或函式,
不管你 new 幾個物件, static 的成員或函式始終指向同樣的記憶體位置,
所以當你更改 static 的成員的值時
所有 new 出來的物件中的static 的成員的值就都會變了

 
1. 最常見的就是 main(),宣告為 static 可在任何物件存在之前被呼叫。
2. 在需要建立多個 class 使用的公用 method 時: 如 Math 類別,目的在公用,而不需要擁有自己的狀態,用 public static 會較方便,其它像是: java.lang.System、java.swing.SwingUtilites…等。
3. 建立只在 class 中使用的「外包工作用的 method」: 避免被一些 實體 method 任意存取 實體variable/field。因為 static method 沒有 this,不能擅自呼叫 實體method 或 實體variable。

object 以 member access operator 來 access static member,這和透過 class name 來取得 static member 兩者感覺起來一樣,但語意上不太一樣,至少對 sun 的編譯器來說是不一樣的。前者的寫法會使得 object reference 被 push 進 stack 隨即又 pop 掉,所以會平白犧牲掉一點效率,後者則不會。
 
Code Convention也不建議這麼寫
都是建議使用ClassName.staticMember

 
類別包含"資料"和"操作"(或稱方法, 函式).
當產生N個物件時, "資料"被產生N分, 但操作還是只有一份.
因此, "操作"只是被共用來操作N個物件的資料用.
問題是, "一般的操作"只有在物件產生時才可以呼叫,
而"static操作"則在物件產生前就可以呼叫.

 
(Kalin's 心得)
回歸Beetle...
第二個Beetle印出字串static Insect.x1 initialized, 那是因為執行Beetle時, 雖然在main()裡沒有做任何事, 但是Beetle extends Insect, 而prt()這個method被宣告為static , 所以在執行Beetle時會先跑base class (Insect)的prt()這個mathod.





 
session 2)
 

" base class 建構完成之後,其 instance variable(譯注:亦即資料成員,相對於 class variable)會以其出現次序被初始化 ... "


 


再次複習一下 :


instance variable => non-static field(field: data member)
class variable => static field


 
 
class Insect
{
    int i=9;
    int j;
 
    Insect()
    {
        prt("i="+i+",j="+j);
        j=39;
    }
 
    static int x1=prt("static Insect.x1 initialized");
 
    static int prt(String s)
    {
        System.out.println(s);
        return 47;
    }
}
 
public class Beetle extends Insect
{
    Beetle()
    {
        System.out.println(prt("j="+j));
    }
    public static void main(String[] args)
    {
        Beetle b = new Beetle();
    }
}
---------- java ----------
static Insect.x1 initialized
i=9,j=0
j=39
47
Normal Termination
輸出完成 (耗費 0 秒)。

 
(Kalin's 心得)
 
接上一個部份,
 
step 1 :
執行Beetle時, 會先到父類別Insect執行static method prt(), 而印出 static Insect.x1 initialized,
 
step 2 :
因為Beetle的main()裡面new了自己, 所以先去始執行父類別Insect的constructor, 印出 i=9,j=0, 然後把39給class variable j,
 
step 3 :
再接著執行自己的constructor, Beetle() 裡面是System.out.println(prt("j="+j));, 所以先執行了prt("j="+j), 所以利用了super印出了j=39, 最後執行System.out.println(prt("j="+j));, 因為Insect的prt()是return 47, 所以最後印出了47.
 


 
 
session 3)
 
最後再練習一次...
 
class Insect
{
    int i=9;
    int j;
 
    Insect()
    {
        prt("i="+i+",j="+j);
        j=39;
    }
 
    static int x1=prt("static Insect.x1 initialized");
 
    static int prt(String s)
    {
        System.out.println(s);
        return 47;
    }
}
 
public class Beetle extends Insect
{
    int k=prt("Beetle.k initialized");
    Beetle()
    {
        System.out.println(prt("k="+k));
        System.out.println(prt("j="+j));
    }
    public static void main(String[] args)
    {
        Beetle b = new Beetle();
        prt("Beetle constructor");
    }
}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
---------- java ----------
static Insect.x1 initialized
i=9,j=0
Beetle.k initialized
k=47
47
j=39
47
Beetle constructor
Normal Termination
輸出完成 (耗費 0 秒)。

 
(Kalin's 心得)
 
幹! 本來是要寫作業的, 竟然花了那麼久的時間來釐清 static... 嗚~
(繼續閱讀...)
文章標籤

Kalin 發表在 痞客邦 留言(1) 人氣(377)

  • 個人分類:Java
▲top
1

自訂側欄

自訂側欄

個人資訊

Kalin
暱稱:
Kalin
分類:
不設分類
好友:
累積中
地區:

熱門文章

  • (214)EJ B 架構
  • (26)Yi na ba yu ddia (朋友你好嗎)
  • (23)This is a war! (口水篇)
  • (13)Megadeth, Ashes in Your Mouth
  • (10)十二生肖的由來
  • (8)煙火
  • (7)My fxxking Beans
  • (7)雪雪雪!!!
  • (5)陳綺貞, 華麗的冒險, Self
  • (5)實踐01: 引數以 by value 方式傳遞, 而非以 by reference 方式傳遞

文章分類

  • 心情筆記 (1)
  • 腦筋急轉彎 (1)
  • EJB (2)
  • Practical Java (1)
  • 娛樂 (1)
  • Music (4)
  • Study in UEA (1)
  • Java (3)
  • 生活 (2)
  • 未分類文章 (1)

最新文章

  • 十二生肖的由來
  • My fxxking Beans
  • This is a war! (口水篇)
  • Yi na ba yu ddia (朋友你好嗎)
  • 雪雪雪!!!
  • 煙火
  • Megadeth, Ashes in Your Mouth
  • 實踐01: 引數以 by value 方式傳遞, 而非以 by reference 方式傳遞
  • EJ B 架構
  • 陳綺貞, 華麗的冒險, Self

最新留言

  • [08/09/17] [string not found (whatsnew.missing.displayname)] 於文章「雪雪雪!!!...」留言:
    We are sure that you cant get ...
  • [08/04/21] [string not found (whatsnew.missing.displayname)] 於文章「雪雪雪!!!...」留言:
    World Of Warcraft gold for che...
  • [07/06/12] TC 於文章「兄弟分酒...」留言:
    1、先把3L裝滿 2、把3L的倒進5L 3、再把3L裝滿...
  • [06/02/19] 子 於文章「十二生肖的由來...」留言:
    hello your school is beautif...
  • [06/02/11] Anita 於文章「十二生肖的由來...」留言:
    真是有趣的故事 !! ...
  • [06/01/05] Claire 於文章「My fxxking Beans...」留言:
    我是說真的...=.= 良心的建議,不要選羅撥.......
  • [06/01/03] Kalin 於文章「My fxxking Beans...」留言:
    哈哈... 學姐, 先謝謝啦! 有了第一學期的經驗後, ...
  • [06/01/02] Claire 於文章「My fxxking Beans...」留言:
    看了,很有趣.... 等你回台灣,有沒有興趣到我的Team來...
  • [05/12/13] Jamie 於文章「This is a war! (口水篇)...」留言:
    辛苦了, 大家在撐一下就放假了!...
  • [05/11/21] GAYA 於文章「陳綺貞, 華麗的冒險, Self...」留言:
    想問你..如果我想把這個http://switchboard...

動態訂閱

文章精選

文章搜尋

誰來我家

參觀人氣

  • 本日人氣:
  • 累積人氣: