Presentation is loading. Please wait.

Presentation is loading. Please wait.

Ch03 物件導向程式設計_物件與類別 JAVA 程式設計入門(II).

Similar presentations


Presentation on theme: "Ch03 物件導向程式設計_物件與類別 JAVA 程式設計入門(II)."— Presentation transcript:

1 Ch03 物件導向程式設計_物件與類別 JAVA 程式設計入門(II)

2 本章大綱 物件導向程式設計介紹 類別與物件 屬性 方法 建構子 方法多載 9/10/2017

3 物件導向程式設計 「物件導向程式設計」是將真實世界中物件使用 上的優點,套用在程式設計上。 物件導向的一些優點: 使用者的角度
封裝(Encapsulation):資訊隱藏,看不到內部運作, 內部也不受外界影響 介面(Interface):人機溝通介面 多型(Polymorphism):以不同的方式實作,作同樣的 功能 製造者的角度 繼承(inheritance):使用舊有設計,再加添新功能

4 物件導向程式設計的優點 子物件之間以介面結合:透過介面,將數個物件結 合在一起,解決一個大問題

5 物件導向程式設計的優點 物件導向程式滸最重要的功能為程式碼的再利用,使用封裝、繼承、介面與多型 更換子物件

6 物件導向程式設計的優點 使用多型(介面相同)

7 抽象化 設想物件「能做什麼」就是抽象化。 抽象化是設計「物件藍圖」的第一步,也是最重要的一步。
物件內部如何運作而達到某個功能,並不是抽象化的責任。

8 物件間訊息傳遞 程式中的物件是經過擬人化的。 物件有自己的名字,有自己的能力。 物件之間的訊息傳遞:

9 物件分類與類別 分類的功能: 每個分類都可成為資訊貯存的索引 分類可以歸納出「通則」 每個分類都有詮釋的功能

10 器具分類 器具的設計通常會延用某些舊的設計,  延用舊的部份即是「繼承」的概念。

11 根據藍圖(類別)可以生產許多產品(物件)
程式中的類別是物件設計藍圖,物件的功能全依類 別的定義來決定 類別就是自訂的資料型別

12 類別與物件 如果類別是設計圖, 物件就是利用設計圖實作出來 的東西 類別可想成是使用者定義的資料型態, 物件是以類 別宣告出來的變數

13 類別的定義 類別的定義語法 三者順序沒有限制 Java合法程式段落的最小單位為類別
之前的程式之類別定義只是當做起始方法main()的 包裹類別,沒有建立該類別的實體 修飾字 class 類別名稱 //類別的標頭 { // 屬性宣告 // 建構子定義 // 方法定義 }

14 類別的修飾字 public-公開類別,宣告成此種類別可以被任何 類別所使用。
一個檔案如果有多個類別時, 一個為public, 其他不可再 為public 無修飾字(default)類別,此種類別僅能被同一 套件(package)內的類別使用。 final-此種類別不可被繼承。 abstract-此為抽象類別的修飾字。此種類別至 少擁有一個抽象方法,不可用於直接建立物件。

15 類別的命名規則(非硬性規定) 類別名稱的第一個字母應該大寫,如:Car、 Person。
若是由兩個字以上組成時,每個單字的第一個字 母為大寫,如:CarClass。 名稱中包括縮寫時,所有縮寫字母為大寫,如: URL。 class EmptyClass { }

16 建立物件 宣告物件 建立物件實體 宣告並建立物件實體 物件名稱必須是合法的識別字。 其命名規則為第一個字的字母皆為小寫。
若為複合字時,其餘字的第一個字母為大寫。 若為縮寫字母時,皆為小寫。 類別名稱 物件名稱; 物件名稱 = new 類別名稱(); 類別名稱 物件名稱 = new 類別名稱();

17 範例1:EX7_1.java宣告及初始化兩個物件
class EX7_1 { public static void main(String [] args) EmptyClass emptyClass = new EmptyClass(); EX7_1 ex7_1 = new EX7_1(); System.out.println(emptyClass); System.out.println(ex7_1); } //空類別定義 class EmptyClass 程式於程式區/java(2)/Ch2/EX7_1.java

18 範例1:EX7_1.java結果

19 屬性(attribute) 屬性就是變數,屬性變數,欄位變數 屬性要在類別內,方法外或建構子外宣告 屬性的宣告語法 存取權限相關的修飾字
public-公用級,所有類別皆可使用此級屬性。 protected-保護級,同一套件內及其子類別可以直接 使用。 無修飾字-預設級(default)或稱套件級,同一套件內 的類別可以直接使用。 private-私有級,屬性所在的類別才能使用。 修飾字 資料型態 屬性名稱;

20 範例2:EX7_2.java屬性存取修飾字的權限
class AccessTest { public int pub = 1; protected int pro = 2; int def =3; private int pri =4; boolean att; //未初始化的變數 int[] arr; EX7_2 ex7_2; } class EX7_2 { public static void main(String [] args) AccessTest at = new AccessTest(); System.out.println(at.pub); System.out.println(at.pro); System.out.println(at.def); //System.out.println(at.pri); //不可使用物件的 private屬性 System.out.println(at.att); System.out.println(at.arr); System.out.println(at.ex7_2); } 程式於程式區/java(2)/Ch2/EX7_2.java

21 屬性 使用final修飾字自訂常數(設定成不能變更的常 數),宣告時同時設定其值
static修飾者為類別屬性, 類別屬性是同一類別中 所有物件所共有,而不專屬於某個物件 取用物件的屬性: 使用點(dot)運算子指出取用 的屬性 屬性只要宣告就會自動初始化,設上預設值 整數:0 浮點數: 0.0f或0.0d 布林值: false 參照變數: null public final int wheels = 4; 物件名稱.屬性名稱

22 範例3:EX7_3.java物件屬性與類別屬性 class EX7_3 { int i = 0; static int s = 100;
public static void main(String [] args) EX7_3 obj1 = new EX7_3(); EX7_3 obj2 = new EX7_3(); System.out.println(++obj1.i); System.out.println(++obj1.s); System.out.println(obj2.i += 10); System.out.println(obj2.s += 10); System.out.println("obj1.s=\t" + obj1.s); System.out.println("obj2.s=\t" + obj2.s); System.out.println("EX7_3.s=" + EX7_3.s); System.out.println("s=\t" + s); } 程式於程式區/java(2)/Ch2/EX7_3.java

23 範例3:EX7_3.java物件屬性與類別屬性 類別成員和物件成員的區別

24 範例4:EX7_4.java指向同類別的參照變數
class EX7_4 { int i; EX7_4 ex; public static void main(String [] args) EX7_4 obj = new EX7_4(); obj.ex = new EX7_4(); obj.ex.i = 1; obj.ex.ex = new EX7_4(); obj.ex.ex.i = 2; System.out.println(obj.i); System.out.println(obj.ex.i); System.out.println(obj.ex.ex.i); } 程式於程式區/java(2)/Ch2/EX7_4.java

25 範例4:EX7_4.java指向同類別的參照變數
物件的鏈結

26 方法 定義方法 修飾字、形式參數列和return敘述為非必要。 資料型別和方法名稱為必要。
方法的資料型別必須和回傳值相同。資料型別void表示 不回傳任何值 形式參數列用以接受傳入值的變數,變數型別也要在參 數列中確實宣告 <修飾字> 資料型別 方法名稱(<形式參數列>) { // 方法中的敘述 <return 回傳值;> }

27 方法 方法的命名規則 一般方法名稱的前面部份會是一個動詞,動詞應全 為小寫。 動詞後的字,第一個字母為大寫。
若方法是為了設定或取得private屬性,則分別使用 「set屬性名稱」和「get屬性名稱」。

28 方法 形式參數式中,以逗號分隔各個形式參數 static修飾方法時,該方法為類別方法 抽象方法沒有實作,無方法主體
public int getArea(int w, int h) { return w*h; } abstract <修飾字> 資料型別 方法名稱(<形式參數列>);

29 方法的呼叫 呼叫方法的語法 參數列的工作是把參數傳給方法。 參數列為選擇性的功能,視方法定義的形式參數列 而定。
物件名稱.方法名稱(<參數列>)

30 方法的呼叫 呼叫方法時的程式走向

31 範例5:EX7_5.java呼叫方法 class EX7_5 {
public static void main(String [] args) System.out.println("We love"); listTree(); System.out.println("and"); System.out.println("love us!"); } //listTree方法定義 static void listTree() System.out.println(" * "); System.out.println(" *** "); System.out.println(" ***** "); System.out.println("*******"); 程式於程式區/java(2)/Ch2/EX7_5.java

32 範例1:EX7_5.java呼叫類別方法 class EX7_5 {
public static void main(String [] args) System.out.println("We love"); listTree(); //呼叫類別方法 System.out.println("and"); listTree(); System.out.println("love us!"); } //listTree方法定義,此方法為類別方法 static void listTree() System.out.println(" * "); System.out.println(" *** "); System.out.println(" ***** "); System.out.println("*******"); 程式於程式區/java(2)/Ch3/EX7_5.java

33 方法的型別與回饋值 傳值和傳參照 基本型別(boolean、byte、short、int、long、 char、float及double)是以傳值的方式回傳。 自訂型別(陣列或物件)是以傳參照的方式回傳資 料。

34 範例2:EX7_6.java呼叫物件方法 class EX7_6 {
public static void main(String [] args) int a = 2; byte b = 6; double c = 5.0; EX7_6 obj = new EX7_6(); //建立物件 obj.listStar(a); //呼叫物件的方法 obj.listStar(b); obj.listStar( (int)c ); } //listStar方法定義 void listStar(int n) { while(n-->0) System.out.print("*"); System.out.print("\n"); } 程式於程式區/java(2)/Ch3/EX7_6.java

35 範例2:EX7_6.java方法的呼叫 參數只傳遞數值

36 傳參照呼叫 陣列名稱和物件名稱為參照變數 當方法的參數是基本資料型別時, 為傳值
當參數是陣列或物件時, 是以參照傳入,而參照即 為實體的位址 當方法取得的是參照時, 操作的是照所指向的陣列 實體, 因此, 實體內容會被改變

37 範例3:EX7_7.java參照變數的傳遞 class EX7_7 { //程式起始方法
public static void main(String [] args) int[] arr = {9, 4, 5, 1, 6, 8}; System.out.println("main內arr的參照: "+arr); showArr(arr); //呼叫顯示陣列內容的方法 sortArr(arr); //呼叫排序方法 } //顯示陣列內容 static void showArr(int[] a) for(int i=0; i<a.length; i++) System.out.print(a[i]+"\t"); System.out.print("\n"); 程式於程式區/java(2)/Ch3/EX7_7.java

38 陣列arr和a是指向同一個實體陣列,所以對arr或a陣列作任何更動時, 皆對同一個陣列作用
//選擇排序 static void sortArr(int[] a) { System.out.println("sortArr內a的參照: "+a); for(int i=0; i<a.length-1; i++) for(int j=i+1; j<a.length; j++) if(a[i] > a[j]) int temp = a[i]; a[i] = a[j]; a[j] = temp; } 陣列arr和a是指向同一個實體陣列,所以對arr或a陣列作任何更動時, 皆對同一個陣列作用 Return之後只能接一個運算式或變數,也就是一個變數,如果要傳遞 兩個變數以上,只要將多個變數放在陣列或物件中即可

39 範例4:EX7_8.java求最大因數 class EX7_8 {
public static void main(String [] args) int num, factor; if(args.length<1) System.out.println("請傳入一大於零的整數!"); return; //返回 } num = Integer.parseInt(args[0]); //將程式參數轉換成整數 if(num < 2) System.out.println("整數必須大於1!"); factor = maxFactor(num); if(factor==0) System.out.println(num+"為質數!"); else System.out.println(num+"的最大因數為"+factor); //求最大的因數 static int maxFactor(int n) { for(int i=n-1; i>1; i--) if(n%i == 0) return i; //回傳找到的因數 return 0; //找不到小於本身的因數 } 程式於程式區/java(2)/Ch3/EX7_8.java

40 範例5:EX7_10.java //顯示陣列內的元素值 static void showArr(int[] a) {
for(int i=0; i<a.length; i++) System.out.print(a[i]+"\t"); System.out.print("\n"); } class EX7_10 { public static void main(String [] args) int[] ori = {5, 2, 0, 7, 8, 9}; int[] dup; dup = duplicateArray(ori); System.out.println("ori: " + ori); showArr(ori); System.out.println("dup: " + dup); showArr(dup); } //複製陣列 static int[] duplicateArray(int[] a) int[] b = new int[a.length]; for(int i=0; i<a.length; i++) b[i] = a[i]; return b; //回傳陣列參照 程式於程式區/java(2)/Ch3/EX7_10.java

41 變數的有效範圍 大括弧{ }是變數領域的藩籬 若一個變數於某個區塊內宣告,則區塊內從宣告點以下 為變數的領域。 區塊外不為變數的領域。 {
int j=1; } j++; //錯誤,無法識別變數j

42 變數的有效範圍

43 範例1:EX7_11.java static void methodName(int a) { int b = 2;
System.out.println("a:"+a); System.out.println("b:"+b); for(int c=0; c<10; c++) { if(c==3) System.out.println("c:"+c); } int c = 4; //此C非前面的C if(c==4) { System.out.println("c:"+c); int e=5; System.out.println("e:"+e); { int f=6; System.out.println("f:"+f); 程式名:EX7_11A.java

44 變數的有效範圍 屬性也稱為欄位變數。 方法內的變數稱為自動變數或區域變數。
自動變數和欄位變數同名是合法的情況,不過 兩者若同名,則欄位變數會因為被遮蔽而無法 在方法內被「看到」。 欲在方法內看到同名的屬性時,可以使用this 關鍵字,指出使用的是物件本身的屬性。 This表示物件的參照,可以用來指出物件屬性 或類別屬性;但是,this不能在類別方法內使 用,因為類別方法位於類別之內,沒有所屬的物 件 this.屬性名稱

45 範例2:EX7_12.java int a =10; //屬性 int b = 20; //屬性
public static void main(String [] args) { EX7_12 obj = new EX7_12(); obj.myMethod(1); } //myMethod方法 void myMethod(int a) { System.out.println("方法內 a:" + a); System.out.println("方法內 this.a:" + this.a); { { int b=2; System.out.println("巢狀區塊內 b:" + b); System.out.println("巢狀區塊內 this.b:" + this.b); System.out.println("區塊內 b:" + b); System.out.println("區塊內 this.b:" + this.b); 程式名:EX7_12.java

46 變數的有效範圍

47 方法多載 同一類別中,若定義數個相同名稱的方法,而各 方法所需的參數不同時,稱為方法多載 (Overloading)。
多載方法是以傳入的參數個數及參數型別做為呼 叫的判斷依據。 多載方法的形式參數的個數及型別相同時,為非 法定義。 多載的目的是因應不同的傳遞資料,讓方法更有 彈性。

48 範例7:EX7_17.java測試多載子 public static void main(String [] args)
{ testVar( 9, 6 ); testVar( 7 ); testVar( (byte)6 ); testVar( 2.5 ); testVar( '中' ); } static void testVar(byte n) { System.out.println("傳入一個byte型別參數"); static void testVar(int n) { System.out.println("傳入一個int型別參數"); // 取消下段的標註符號將出現錯誤: testVar(int) is already defined /* static int testVar(int n) { System.out.println("傳入一個int型別參數"); return n; } */

49 範例7:EX7_17.java測試多載子 static double testVar(double n)
{ System.out.println("傳入一個double型別參數"); return n; } static void testVar(int n, int m) { System.out.println("傳入兩個int型別參數");

50 建構子(constructor) 何謂建構子:以一個方法來設定物件屬性的初 值,可視建構子為一個特殊的方法
建構子的目的:當產生一個物件的同時,同時將 屬性初值進行設定

51 建構子 使用new及建構子建立物件 物件名稱 = new 類別名稱(); 呼叫建構子

52 範例1:建構子 class ConstructorDemo { public static void main(String args[])
{ Student Peter=new Student(); System.out.println(" Peter的資料-->使用Student()建構式") ; Peter.getShow() ; Student David=new Student(1000) ; System.out.println(" David的資料-->使用Student(1000)建構式") ; David.getShow() ; Student Mary =new Student(48, 150) ; System.out.println(" Mary的資料 -->使用Student(48, 150)建構式") ; Mary.getShow() ; } 程式名:Exa6-1.java

53 範例1:建構子 class Student { private int height, weight ; Student()
} Student(int w) //Student類別的建構式,須設定一個引數 { setWeight(w) ; //呼叫setWeight方法初始化weight資料成員 height=50 ; //初始化height資料成員的值為50 Student(int w, int h) //Student類別的建構式,須設定兩個引數 { setWeight(w) ; setHeight(h) ;

54 範例1:建構子 void setWeight(int w) { if (w>=40 && w<=150) weight=w ;
else weight=40; } void setHeight(int h) { if (h>=50 && h<=250) height=h ; height=50; void getShow() { System.out.println(" 身高是: "+height); System.out.println(" 體重是: "+weight + "\n");

55 預設的建構子 沒有定義建構子的類別時,編譯器會自動設給一 個沒有形式參數的建構子(預設建構子)。
預設的建構子是沒有內容的,不會對物件的屬性 有任何影影響。 Constructor的名稱必須和類別擁有相同的名稱才 可以 Constructor沒有傳回型態,即使void也不需要 Constructor也可以多載,其做法和方法多載一 樣,是使用不同的引數串列的個數和引數串列的 資料型別來加以區隔constructor

56 預設的建構子 如果在定義類別時,若有定義至少一個建構子, 則編譯器不會設給任何預設建構子。
此時,程式設計者必須自己定義,如範例1中的 Student()。如果範例1中的屬性(height, weight)在 宣告時也給了初始值(或Java在宣告後自動設定初 始值為0),則建構子Student()內是空的

57 定義建構子 建構子的名稱一律同類別名稱,而且不宣告回傳 資料型別。
建構子的修飾字可以為public、protected、 private或無修飾字。 建構子修飾字不使用static和abstract。 修飾字 類別名稱(形式參數列) { //程式敘述 }

58 定義建構子 建構子也可以多載 class SomeClass { public SomeClass() //不使用參數建立物件 }
public SomeClass(int x, int y) //使用參數建立物件

59 建構子的呼叫 建立物件時呼叫建構子 方法可以和建構子同名。有回傳型別者為方法; 反之,無回傳型別者為建構子。
類別名稱 物件名稱 = new 類別名稱(形式參數列);

60 範例2:EX7_19.java class EX7_19 //程式起始方法
{ public static void main(String [] args) { Rectangle rect1 = new Rectangle(); //以沒有參數的建構子建立物件 System.out.println("rect1的面積為:" + rect1.getArea()); Rectangle rect2 = new Rectangle(3, 4); //以需要兩個參數的建構子建立物件 System.out.println("rect2的面積為:" + rect2.getArea()); }} class Rectangle //Rectangle類別定義 { int height; //高 int width; //寬 public Rectangle() //沒有參數的建構子 { height = 1; width = 1; } public Rectangle(int height, int width) //需要兩個參數的建構子 { this.height = height; //區域變數會遮敝屬性 this.width = width; } public int getArea() //求得面積的方法 { return height*width; }}

61 範例2:EX7_19.java延伸 class EX7_19 //程式起始方法
{ public static void main(String [] args) { Rectangle rect1 = new Rectangle(); //以沒有參數的建構子建立物件 System.out.println("rect1的面積為:" + rect1.getArea()); Rectangle rect2 = new Rectangle(3, 4); //以需要兩個參數的建構子建立物件 System.out.println("rect2的面積為:" + rect2.getArea()); }} class Rectangle //Rectangle類別定義 { int height; //高 int width; //寬 public Rectangle() //沒有參數的建構子 { height = 1; width = 1; } public Rectangle(int height, int width) //需要兩個參數的建構子 { height = height; //區域變數會遮敝屬性 width = width; } public int getArea() //求得面積的方法 { return height*width; }} 程式名:EX7_19_3.java, 另外,還有一個測試程式EX7_19_2.java 結果??

62 範例2:EX7_19.java延伸(結果)

63 使用this() 建構子多載時,建構子可以呼叫其它建構子,不過有以下限制: 必須使用 this() 取代類別名稱()。
只能在第一個敘述呼叫。 不能造成建構子遞迴。

64 封裝 封裝的特點: 隱藏類別實作的細節。 強迫使用者透過方法來操作屬性,如此可以保護資 料不會被濫用。 使程式碼更容易被維護。

65 封裝 沒有封裝的 物件:兩個使用者 可以同時要求設定 屬性一 完整封裝 的物件:使用者必 須透過方法來設定 屬性一時,此時二
人必須排隊來使用 方法

66 完整封裝的物件 屬性宣告為private 會設定一些方法來取用屬性,而這些方法為 public

67 範例5:EX7_22.java class EX7_22 { //程式起始方法
public static void main(String [] args) 銀行帳號 哈利 = new 銀行帳號("8888", 100); 哈利.存款(2000); 哈利.提款("6666", 10000); 哈利.提款("8888", 10000); 哈利.查詢("8888"); 哈利.提款("8888", 1000); //System.out.println(哈利.金額); //錯誤 //哈利.查詢(); //錯誤 } 程式名:EX7_22.java

68 範例5:EX7_22.java class 銀行帳號 { private String 密碼; private int 金額;
銀行帳號(String 密碼, int 開戶金) { this.密碼 = 密碼; 金額 = 開戶金; System.out.print("恭喜開戶成功! "); 查詢(); //呼叫查詢方法 } public void 存款(int 存入金) { 金額 += 存入金; System.out.print("完成存入! "); 查詢(); //呼叫查詢方法 }

69 public void 提款(String 密碼, int 提出金)
{ if( this.密碼.equals(密碼) ) { if(提出金 <= 金額) { 金額 -= 提出金; System.out.print("完成提出:"+ 提出金 +" "); 查詢(); //呼叫查詢方法 } else System.out.println("剩餘金額不夠提出:"+提出金); System.out.println("密碼錯誤!"); private void 查詢() { System.out.println("目前金額:" + 金額); } public void 查詢(String 密碼) { if( this.密碼.equals(密碼) ) 查詢(); //呼叫查詢方法

70 大富翁.java class 骰子 { static int 擲骰子() return (int)(Math.random()*11+2);
9/10/2017 class 大富翁 { public static void main(String [] args) 玩家 [] A = new 玩家[4]; A[0] = new 玩家(); A[1] = new 玩家(); A[2] = new 玩家(); A[3] = new 玩家(); A[0].名字 = "趙一"; A[1].名字 = "王二"; A[2].名字 = "張三"; A[3].名字 = "李四"; for(int i = 0; i < 20; i++) System.out.println("第" + i + "輪:"); for(int j = 0; j < 4; j++) A[j].位置 = A[j].位置 + 骰子.擲骰子(); if (A[j].位置 >= 40) A[j].位置 = A[j].位置 - 40; System.out.println(A[j].名字 + "的位置在" + A[j].位置); } class 骰子 { static int 擲骰子() return (int)(Math.random()*11+2); } class 玩家 String 名字; int 錢 = 10000; int 位置 = 0;


Download ppt "Ch03 物件導向程式設計_物件與類別 JAVA 程式設計入門(II)."

Similar presentations


Ads by Google