1 / 47

類別與物件概念

類別與物件概念. 類別的定義 : class class_name { 類別成員宣告 }. 物件導向 程式設計 (Object Oriented Programming, OOP ):. 將一組彼此相關的方法( Method )和屬性( Properties )封裝起來,變成一個「 類別 」。 類別的「方法」 ( Method ) 類別的「 屬性 」( Properties ) 「物件」是「類別的實例( an instance of a class )」

lynnea
Download Presentation

類別與物件概念

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. 類別與物件概念 • 類別的定義: class class_name{類別成員宣告}

  2. 物件導向程式設計(Object Oriented Programming, OOP): • 將一組彼此相關的方法(Method)和屬性(Properties)封裝起來,變成一個「類別」。 • 類別的「方法」 (Method) • 類別的「屬性」( Properties) • 「物件」是「類別的實例(an instance of a class)」 • 類別有 封裝(encapsulation)、多型(polymorphism) 、繼承(inheritance) 的特性. • 類別間以相互傳遞訊息(message) {以get方法,set方法}來溝通,每一種訊息在物件中的反應程序稱為方法(method).

  3. 物件導向的三大特性 • 封裝 • 封裝是將類別中的程式碼或是資料保護起來,避免受到外界不當的干擾或是使用。 • 繼承 • 繼承的概念來自於階層式的分類。主要的目的是在定義新類別時,不需要重覆的定義相同的屬性或是方法。 • 多型 • 「一個介面,多種使用方法」。

  4. 封裝(encapsulation) 根據類別成員的特性分成 private、protected和public等三個封裝等級,也就是存取類別成員的權限等級。 • 在 private 區域的屬性或方法 • 不能被繼承 • 外部程式不能直接存取 • 當需要存取 private 的成員時,只能透過 public 區提供的(get, set)方法。 • 在 protected 區的成員 • 可以被繼承。被指定成protected的屬性或方法,同套件(目錄)中的所有類別均可使用。 • 在 public 區的成員 • 外部程式可以直接存取。 • 沒有指定修飾子的欄位或方法,識同private。

  5. encapsulation (封裝) 示意圖 • 物件的屬性(Properties)都被method所包圍,以確定得到正確的操作

  6. 物件與類別的初體驗: • (Class)是產生物件的模板,不同的模板可以產生不同特性的物件。 • (Object)是物件導向程式語言的基本元件。 • Java 程式是由類別所組成 因此完整的程式至少要有一個類別 • 字串 String就是一種類別 (class),而利用 String 類別就可以產生具有 String 特性的物件。程式碼如下:

  7. 類別基本架構: • 在一個 *.java 檔裡只能有一個 public 類別,而且此檔名必須與此public類別同名。若檔案中無public類別, 則檔名可以不必和類別同名。 • main() 一定要宣告成 public staticstatic 表示main() 在沒有建立物件的情況下仍然可以被執行 • 類別基本架構:類別通常包括三個成員,屬性、方法、建構子(方法)。 • 在物件導向程式語言中,將專屬於類別的函數稱之為方法(Methods)。 class 類別名稱 { class properties; //屬性 instance properties;//屬性 class methods; //方法 instance methods; //方法 類別名稱(); //建構子 public static void main(String args[]); } 回Java物件導向

  8. 存取權限 一個類別中只有被宣告為public 的成員可以被此類別所宣告的物件直接存取 類別內的方法, 可以放心地 存取類別內的 private成員   雖是用 ClassA 宣告成的物件, 但是卻不能存取 其 private 成員

  9. 物件的空間配置 • 將類別實體化出多個物件時,每個物件都會有獨立的儲存空間。例如以下的程式碼: class Vehicle //定義的類別 { int wheel; } //定義一個實體變數 Vehicle newCar1= new Vehicle();//實體化一個類別 Vehicle newCar2 = new Vehicle();//再實體化一個類別 Vehicle rCar= newCar1; //只是一個參考

  10. 建立資料存set取get的方法 • 除了特殊的情況之外,類別中的資料成員不太可能讓外界直接的存取。否則,使用者可能在未經核對的情況下,任意的修改資料的內容。 • 存取資料成員一般是透過類別中設計的方法來達成,我們也可以在方法中加上資料存取的限制。 • 設定資料成員的值 public void setWheel(int n) //定義方法,設定wheel的值 { if (n>0) wheel = n; } • 取出資料成員的值 public int getWheel() //定義方法,傳回wheel的值 { return wheel; }

  11. 類別 中的資料欄稱為屬性(Properties)。 類別 中的屬性可分為兩個大類,1.專屬於物件的 instance屬性2.屬於類別的 static屬性 類別的屬性 • 例如:當我們建立一個整數物件v1如下: • Integer v1=new Integer(95); • 則v1物件包含MAX_VALUE、MIN_VALUE、TYPE等三個類別屬性。 • 使用物件和屬性時以 “.”隔開,格式如下: • 物件名稱.屬性名稱ex: v1. MIN_VALUE • Integer . MIN_VALUE

  12. 建構子的使用 • 建構子在物件建立時立即會執行,所以,我們可以在建構子中初始化相關的成員。 • 建構子的名稱必需和類別的名稱相同,建構子可以有傳入的參數,但建構子不能自訂回傳的型態 。 • 因為建構子的回傳型態就是物件本身。 • 定義建構子: class Vehicle //定義的類別 { private int wheel; //定義一個實體變數 public Vehicle() //類別的建構子 { wheel = 4; } }

  13. 靜態(static)屬性 • static欄位的重要觀念 • 同一類別中, 使用含有static屬性之類別所建立的物件,彼此可以共同存取同一個靜態屬性。不論您對 該類別建立多少個物件,屬於靜態的屬性只保存一份而已 • static屬性除了物件可使用之外,也可以直接使用類別呼叫 • 這種 變數稱為類別變數 (class variable),也稱為靜態屬性欄 (static field),靜態屬性的使用 物件名稱.靜態屬性名稱;或 類別名稱.靜態屬性名稱; public class Circle{ static double PI=3.14159;//不論是何種圓其圓周律皆同double x; double y; double radius;} 含有靜態變數的類別必須獨立於方法之外(不可放在方法內),就像宣告全域變數時,必須在方法之外宣告一樣。 回Java物件導向

  14. 靜態(static)方法 • 靜態(static)方法並不屬於任何一個物件,我們不需要事先建立一個新的物件,就能直接使用該method。 • 因為static方法不需物件就可執行,因此這種方法不能存取instance變數,您若存取instance變數會產生語法錯誤。 • static方法的宣告 static 資料型態 類別方法名稱() { 靜態方法程式碼 } • static方法的使用 類別名稱.靜態方法名稱();//EX:Math.sin(45) (Math is a classname) • static方法為該類別所有的物件所共同擁有,不論您對 該類別建立多少個物件,屬於類別的方法只保存一份而已,這種 方法稱為類別方法 (class method),也稱為靜態方法 (static method), /* 程式裡的 main() 方法的前頭都冠上一個 static 關鍵字,表 示不須建立物件就可執行 main() 方法。*/ 回Java物件導向

  15. 建立類別基本架構例( 點類別) • 撰寫一個Point類別,內部有1.平面的位置(x,y)屬性2.建構函數3.x的設定方法void setX(int x) • 4.y的設定方法void setY(int y)5.x的傳回方法int getX() • 6.y的傳回方法int getY()7.顯示點物件內容的方法

  16. Point.java public class Point { protected int x, y; public Point() {} public void setX(int x) { this.x=x;} public void setY(int y) { this.y=y; } public int getX() { return x; } public int getY() { return y; } public String toString() { return ("(x,y)=("+x+","+y+")"); } public static void main(String args[]) { //建立Point類別的物件 Point p1=new Point(); p1.setX(20); p1.setY(10); System.out.println(p1.toString()); } }

  17. 建立類別基本架構例(矩形的周長和面積) • 撰寫一個Rectangle類別,內部有1.建構函數 • 2.屬性有長 ,寬, 左上方的頂點 • 3.設定與傳回屬性的兩種方式, • 4.分別計算顯示矩形的周長和面積。

  18. 建立Rectangle類別 public class Rectangle { public Point a=new Point(); int l; int w; //instance私有成員 public Rectangle() { } //建構函數 public void setL(int length) { this.l=length; } public void setW(int width) { this.w=width; } public int getL() { return l;} public int getW() { return w;} public int area() { return l*w;} public int girth() { return 2*(l+w); } public String toString() { return "(x,y)=("+a.getX()+","+a.getY()+")"+ ",(L,W)=("+l+","+w+"),area ="+area();} public static void main(String argv[]) { Rectangle rc=new Rectangle(); a.setX(10);a.setY(20); rc.setL(30);rc.setW(40); System.out.println(rc.toString()); } }

  19. 作業:1.建立一 Circle類別2.建立一 Triangle類別

  20. Circle.java public class Circle { final static double PI=3.14159; //靜態常數 Public a=new Point(); int r;//radius public Circle() {}//(constructor) public void setR(int r) { this.r=r;} public int getR() { return r; } public double area() { return PI*r*r; } public double girth() { return 2*PI*r; } public String toString() { return "(x,y)=("+a.getX()+","+a.getY()+"),r="+ r +",a="+this.area(); } public static void main(String argv[]) { Circle c=new Circle(); a.setX(10); a.setY(10); c.setR(10); System.out.println(c.toString()); } }

  21. 建構函數或(建構子): • 建構函數(Constructor Function)是類別資料成員中的特殊函數,它的名稱與類別名稱相同。 • 當建立新的物件時,會自動執行建構函數一次,利用這個特性,可以用來設定物件的初值。 • 建構函數不能傳回值,所以不必宣告函數的型態。

  22. 參數化的建構子 • 類別中可以同時定義多個建構子,而您也可以將參數傳入建構子中,自行決定資料成員的值。例如: • 使用方式: class Vehicle //定義的類別 { private int wheel; //定義一個實體變數 public Vehicle() //類別的建構子 { wheel = 4;} public Vehicle(int n) //定義有參數的建構子 { this(); wheel = n*4; } } Vehicle newCar1 = new Vehicle(); //實體化一個類別 Vehicle newCar2 = new Vehicle(6); //實體化一個類別,並傳入參數

  23. 預設建構子的使用 • 如果類別未曾定義建構子,則該類別在實體化時JVM會自動建立一個不做任何事的建構子,該建構子如下: • 但如果類別中自行建立了建構子,JVM就「不會」再幫類別建立建構子。 public Vehicle() { }

  24. 方法多載 (Method Overloading) • 方法多載,又可以稱為「重載」、「覆載」,主要目的在於實現物件導向中的「多形」的精神。 • 物件導向程式中允許同一個類別中可以定義相同名稱的方法,這種現象就是「同名異式」。例如: public void sasayHello(int nyHello() public int)

  25. 方法多載… • 當方法多載時,各方法的「簽名 (signature) 」不可以相同。 • 所謂的「簽名」是指方法中參數的個數或是型態,但不包含方法回傳值的型態或是方法的封裝型態。 • 一旦類別中發生了此種現象,我們稱該方法被「多載 (overloaded) 」。 public int add (int i1, int i2) {…} public float add(float f1, float f2) {…} public long add(long l1, long l2) {…}

  26. this • 是一個指向物件本身的參考(亦即『指標』) • 「this」這個字眼我們可以直接把它翻譯成「這個」,在類別中使用時,就可以翻譯成「這個類別」。 • this使用方式 (1)this.類別屬性 (2)this.類別方法 (3)this.實體屬性 (4)this.實體方法 • 注意事項 只能在成員方法中使用,不可寫在主程式中。

  27. this() • 「this()」我們直接翻譯成「這個類別的建構子()」。 • this()規則 (1)只能在建構子中使用this() 。 (2)只能寫在建構子中的第一行敘述。 (3)建構子內呼叫另一建構子時,要用this()這個關鍵字來呼叫。 (4)static method內不可以用this()這個關鍵字來呼叫。

  28. 我們來看看下面這個建構函數例子: public class Std_dat { String id=new String(); String name= new String(); //學生姓名 int math,eng; //數學和國文成績 public Std_dat( ) { } //建構函數一 public void setID(String id) { this.id=id; } public void setName( String name) { this.name=name; } public void setMath(int score) { math = score; } //設定數學成績 public void setEng (int score) { eng = score;}//設定英文成績 public String getName() { return name; }//取得學生姓名 public String getID() { return id; } //取得學生ID public int getMath() { return math; }//取得數學成績 public int getEng () { return eng; }//取得英文成績 public double getAvg() { return(math+eng)/2; } //取得英文和數學成績的平均 public static void main(String args[]) { Std_dat s1= new Std_dat(); s1.setID ("01"); s1.setName ("小明"); s1.setMath(80); s1.setEng (70); System.out.println("學號"+s1.getID()); System.out.println("姓名"+s1.getName()); System.out.println("數學成績"+s1.getMath()); System.out.println("英文成績"+s1.getEng ()); System.out.println("平均成績"+s1.getAvg()); } }

  29. 物件陣列(Array)例

  30. 建立物件陣列 • 要建立物件陣列,首先要建立物件陣列指標,例如: • Std_dat std[ ] =new Std_dat[100]; • 接著再分別指定每一個物件指標對應的物件內容,例如: • std[0]=new Std_dat();//陣列元素0指向的物件 • std[1]=new Std_dat();//陣列元素1指向的物件

  31. Java 之陣列與物件 • myObject 物件的實體:

  32. 以物件為method的參數 // 將Circle 類別中加入 compare()方法 class Circle // 定義類別Circle { . . . // Compare() method public Circle compare(Circle cir1) { if(this.r > cir1.getR()) return this; else return cir1; } }

  33. public class Circle { . . . public Circle compare(Circle cir1) { if(this.r > cir1.getR()) return this; else return cir1; } public static void main(String args[]) { Circle cir1=new Circle(); Circle cir2=new Circle(); cir1.setR(2); cir2.setR(1); Circle temp; temp=cir1.compare(cir2); if(cir1==temp) System.out.println("radius of cir1 is larger"); else System.out.println("radius of cir2 is larger"); } }

  34. 將物件解構 • 只要設定為 null,就可以將物件解構,並釋放出記憶體,程式碼如下: obj4=null;   null跟Null完全不同,沒有Null這種東西

  35. java常用的類別庫 類別庫名稱 說 明 java.applet 存放和applet相關的類別。 java.awt 存放java視窗元件相關的類別。 java.lang Java基本類別,此類別會自動載入。 java.io 存放和I/O相關的類別。 java.net 存放和網路連線相關的類別。 java.util 存放utility相關的類別。

  36. 作業: 設計一個 MyTime 類別,包含三個實體變數 h、m、s,分別表示時,分,秒,一個建構子,三個 get 方法,三個 set 方法,以及一個 toString()方法。請使用 MyTime類別中的 set 方法設定為 12 時 34 分 56 秒,然後使用 toString() 顯示。 public class MyTime { private int h, m, s; public MyTime() { } public int getHour() { return h; } public int getMinute() { return m; } public int getSecond() { return s; } public void setHour(int h) { if (h<=24 && h>=1) this.h=h; } public void setMinute(int m) { if (m>=0 && m<60) this.m=m; } public void setSecond(int s) { if (s>=0 && s<60) this.s=s; } public String toString() { return h+":"+m+":"+s; } }

  37. (接上題)。在 MyTime 類別中增加一個 addSecond() 方法(每執行一次加一秒),addSecond() 方法格式如下: (請考慮 分 與 時 的變化) public int addSecond() { //寫出您的程式碼 } • 然後寫一TestTime.java程式類別,使用set 方法設定為 12 時 58 分 59 秒,然後以for迴圈呼叫 addSecond() 方法100次,同時將時間顯示出來(請注意 時 與 分 的變化)。

  38. 設計一個 MyDate類別,包含三個實體變數 y、m、d,分別表示年月日,一個建構子 MyDate(),一個私用方法 checkDay(),以及一個 toString() 方法。請設計一個程式使用 MyDate 類別的建構子設定為 2003 年4 月 30 日,然後使用 toString() 顯示。 public class MyDate { private int y, m, d; public MyDate(int y, int m, int d) { this.y = y; if (m >= 1 && m <= 12) this.m = m; else this.m = 1; this.d = checkDay(d); } private int checkDay(int d) { int days[] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; if (d > 0 && d <= days[mm]) return d; if (m==2 && d==29 && (this.y%400==0 || (this.y%4==0 && this.y%100!=0))) return d; return 1; } public String toString() { return y + "/" + m + "/" + d; } } }

  39. (接上題) 在 MyDate 類別中增加一個 addDay() 方法, addDay() 方法格式如下:(請考慮 年 與月 的變化) public int addDay() { //寫出您的程式碼 } • 然後設計一個TestDate.java程式使用 MyDate 類別的建構子設定為 2003 年 11 月 30 日,然後以for迴圈呼叫 addDay() 方法50次,同時將日期顯示出來(請注意 年與 月 的變化)。

  40. 使用 講義中的MyDate 及 MyTime類別設計一個test.java程式 • 設定日期為 2003 年12 月 25 日,時間為 15 時 45 分 30 秒,然後使用addSecond() 8640000次後,用 toString() 將 日期及時間顯示出來,請問應該為何年何月何日何時何分何秒。

  41. p.44-p48 為MyTime 之範例 Second.java public class Second { private int s; public Second() { s=0; } public void setSec(int s) { if ((s<0)||(s>=60)) s=0; else this.s=s; } public int getSec() { return s; } public int addSec() { s++; if (s==60) { s=0; return 1; } else return 0; } public String toString() { if (s<10) return "0"+s+"."; else return s+"."; } }

  42. Minute.java public class Minute { private int m; public Minute() { m=0; } public void setMin(int m) { if ((m<0)||(m>=60)) m=0; else this.m=m; } public int getMin() { return m; } public int addMin() { m++; if (m==60) { m=0; return 1; } else return 0; } public String toString() { if (m<10) return "0"+m+":"; else return m+":"; } }

  43. Hour.java public class Hour { private int h; public Hour() { h=1; } public void setHour(int h) { if ((h<=0)||(h>24)) h=0; else this.h=h; } public int getH() { return h; } public int addHour() { h++; if (h==24) { h=0; return 1; } else return 0; } public String toString() { if (h<10) return "0"+h+":"; else return h+":"; } }

  44. Mytime.java // 使此檔與 Second.java, Minute.java, Hour.java 同一目錄(檔案夾) public class Mytime { private Hour h=new Hour(); private Minute m=new Minute(); private Second s=new Second(); int sc; int mc; public void Mytime() { } public Hour getHour() { return h; } public Minute getMin() { return m; } public Second getSec() { return s; } public void setHour(Hour h) { this.h=h; } public void setMin(Minute m) { this.m=m; } public void setSec(Second s) { this.s=s; } public void Next() { sc=s.addSec(); if (sc==1) { mc=m.addMin(); if (mc==1) h.addHour(); } } public String toString() { return h.toString()+m.toString()+s.toString(); } }

  45. Test.java // 使此檔與 Second.java, Minute.java, Hour.java, MyTime.java 同一目錄(檔案夾) public class Test { static public void main(String args[]) { Second s=new Second(); Minute m=new Minute(); Hour h=new Hour(); s.setSec(56); m.setMin(58); h.setHour(11); Mytime a=new Mytime(); a.setSec(s); a.setMin(m); a.setHour(h); System.out.println(a.toString()); for (int i=0;i<10000;i++) { a.Next(); System.out.println(a.toString()); } } }

  46. MyDate.java package ClassLib; public class MyDate { private int y, m, d; int days[] = {0,31,28,31,30,31,30,31,31,30,31,30,31}; public MyDate() { } public void setDate(int y, int m, int d) { this.y=y; this.m=m; this.d=d; } private int checkYear() { if (y%400==0 || (y%4==0 && y%100!=0)) { return 1; } else { return 0; } } private int checkDay(int d) { if (d > 0 && d <= days[m]) { return d; } if (m==2 && d==29 && (this.y%400==0 || (this.y%4==0 && this.y%100!=0))) { return d; } return 1; } public String toString() { return y + "/" + m + "/" + d; } public void decDate() { d=d-1; if (d==0) { m=m-1; switch(m) { case 1: case 3: case 5: case 7: case 8: case 10: case 12: d = 31; break; case 4: case 6: case 9: case 11: d = 30; break; case 2: if (checkYear()==1) d=29; else d=28; break; case 0: y=y-1; m=12; d=31; break; } } }

  47. Continue public void incDate() { d=d+1; { switch(m) { case 1: case 3: case 5: case 7: case 8: case 10: { if (d== 32) { d=1; m=m+1; } } break; case 12: { if (d== 32) { d=1; y=y+1; m=1; } } break; case 4: case 6: case 9: case 11: if (d== 31) { d=1; m=m+1; } break; case 2: if (checkYear()==1) { if (d==30) { d=1; m=3; } } else { if (d==29) { d=1; m=3; } } break; } } } public void IncNDate(int n) { for (int i=0; i<=n; i++) { incDate(); } } public void DecNDate(int n) { for (int i=0; i<=n; i++) { decDate(); } } static public void main(String args[]) { MyDate date=new MyDate(); date.setDate(2008,2,5); date.IncNDate(100); System.out.println(date.toString()); } }

More Related