方法進階及物件導向基礎 Lecturer: 楊昌樺
Outline 方法 (Method) Overloading 遞迴(Recursive) 物件導向概念(OOP) 物件基礎 Your Turn 遞迴(Recursive) 物件導向概念(OOP) 物件基礎 Your Turn – 創作物件, 使用物件的方法
方法(Method)複習 定義 可重複使用的程式碼片段 X=方法名(參數, 參數); 方法傳回型態 方法名稱 (參數宣告); 範例:static int myAdd (int a, int b) { return a*b; } 程式碼位址 記憶體 方法程式碼 a b return
Overloading Overloading 在 Java 中有三種情況可能會造成 method 在類別中或是 superclass 中和其他的 methods 同名 覆蓋 methods(overriding methods) 遮蔽 methods(hiding methods) 名稱過載(name overloading) Overloading 為類似功能的方法統一提供一樣的名稱,但是可以根據 參數個數的不同 參數資料型態的不同 自動呼叫對應的函式。 (這樣設計員可以不用花很多心思想不同的函式名稱)
Overloading Overloading Java 中,以 method 的名稱與參數來決定一個 method 因此,Java 允許多個 methods 共用同一個名字,但必須擁有不同數目或型態的參數以供區分 例: static int square(int num) static double square(double num) 或 static int getMin(int a, int b) static int getMin(int a, int b, int c)
Overloading 圖示 根據參數數目或型態的不同呼叫到不同的程式碼 static int square (int a) { return a*a; } static double square (double a) { return a*a; } X=方法名 (int); Y=方法名(double); 傳回型態 名稱 (參數宣告); 程式碼位址1 程式碼位址2 記憶體 記憶體 方法程式碼 a 方法程式碼 a return return
Overloading Example: OverloadingDemo.java static int square(int num) { return num*num;} static double square(double num) { return num*num; } static int getMin(int a, int b) { if ( a < b ) return a; else return b; } static int getMin(int a, int b, int c) { int min; if ( a < b ) min = a; else min = b; if ( min < c ) return min; else return c;
想想看一個overloading的範例 float squareMeasure(int radius) //圓形面積 { return radius* radius*3.14; } float squareMeasure(int height, int width) //長方形面積 { return height*width; float squareMeasure(int upp, int bot, float height) //梯形面積 { return (upp+bot)*height/2;
多型 (Polymorphism) 同一個介面(方法名稱),多種實際運作方法 設計一個通用的介面給一組相關動作 降低程式分類的複雜性 選擇特定的動作(也就是方法)應用於各種情況是編譯器的工作 程式設計師不需要手動去選擇 只需要記住和使用通用的介面即可
Your Turn 設計一段Code讓以下的Overloading方法 myADD 得以實現 public static void main(String[] args) { int i = 10, j = 5; int k = myADD(i, j); System.out.println("The return value: " + k); int a = 10, b=3; int w = myADD(a, b, 8); System.out.println("The return value: " + w); double y = 10.8, z=3.3; double x = myADD(y, z); System.out.println("The return value: " + x); }
遞迴(Recursive)的方法設計 遞迴(Recursive) 程式設計的一個重要觀念,可以使程式碼變的很簡潔,但是設計此類方法必須很小心,不然很容易掉入無窮迴圈。 定義:一個問題內涵是由本身所定義的話,稱之遞迴 特性: 遞迴方法每次呼叫後,可使問題範圍縮小 方法必須要有一個終止條件,以便結束遞迴方法的執行
遞迴(Recursive) 遞迴的階層函數: 4! = 4*(4-1)! = 4*3! 3! = 3*2! 2! = 2*1! 1! = 1*0! = 1 2! = 2*1! = 2*1 = 2 3! = 3*2! = 3*2 = 6 4! = 4*3! = 4*6 = 24
遞迴(Recursive) Example: FactorialDemo.java static int factorial(int n) { if ( n == 1 ) return 1; else return n * factorial(n-1); }
Your Turn 試遞迴設計 static long fib(int num) 方法來計算某一項的費氏係數 (費氏係數:1, 1, 2, 3, 5, 8, 13, 21, …) 參數 num 為欲計算的項次 提示 fib(1)=1 fib(2)=1 fib(3)=fib(1)+fib(2)=2 fib(4)=fib(3)+fib(2)=3 輸入n,就呼叫fib(n)獲得值
Object-Oriented Programming (OOP) 軟體工程中,一個物件就是一堆相關變數(variables)與相關方法(method)的集合 變數:描述此物件的狀態,或稱屬性(property) 方法:可修改物件狀態的行為 優點:模組化(Modularity)和資訊隱藏(Information Hiding) 例如:腳踏車物件
Object-Oriented Programming (OOP) 訊息(Message) 即物件間彼此傳遞的參數(Parameters) 透過訊息,物件之間可以更緊密地運作 例如:你想將腳踏車變檔
Object-Oriented Programming (OOP) 類別(Class) 是一個藍圖或是原型(prototype)其中定義了某一種類別所需的狀態(variables)、行為(method)和事件(Event) 狀態(variables):一個物件的特性 (身高,體重,年齡) 物件的名詞 行為(method):一個物件會做的動作 (跑,跳,走路) 物件的動詞 事件(event):發生在一個物件上的事情 (被打,跌倒) 物件的受詞(用 message 傳遞)
Object-Oriented Programming (OOP) 類別(Class) 例如:一個腳踏車的類別 用 new 產生出兩個物件:我的腳踏車、你的腳踏車 可以稱為 instance of a class (一個類別的實體)
Object-Oriented Programming (OOP) 物件(Object)與類別(Class)的比較 在真實世界中,物件與類別比較好分辨,因為類別可以當成是物件的樣版或是模子 在軟體概念中,因為是兩者都是抽象概念較難讓人接受 Box box1 = new Box(); Box box2 = new Box(); box1.width = 100; box1, box2將會變成Box的實例 每一個Box物件都有它自己的實例屬性width、height、depth 存取這些成員,使用點(.)運算子,連接物件的名稱與實例屬性的名稱 class Box { double width; double height; double depth; } 這只是一個規格書
Object-Oriented Programming (OOP) 繼承(Inheritance) 一個類別可以繼承他的父類別的狀態以及行為,此時稱為此子類別(subclass)繼承於父類別(superclass)
Object-Oriented Programming (OOP) 繼承(Inheritance) 父類別可直接透過繼承產生子類別 子類別延續父類別的功能,並可外加新功能(method) 例如:登山車要多一個防水功能(method) 子類別也可以覆蓋(override)自父類別而來的功能(method),提供一個自我詮釋方式 例如:登山車繼承了一般腳踏車的換檔功能(changeGears()),但因為登山車需要不一樣的換檔功能,所以它可以覆蓋(override)換檔功能,自己設定一個新的換檔功能。
Object-Oriented Programming (OOP) 介面(Interface) 定義 一段只有常數與函式宣告,但沒有函式實作的程式碼。 作用 讓某個功能,不論由誰實作,都能夠有相同的函式名稱,傳入值,傳出值,與存取範圍 當某個 class 實作 interface,即代表該 class 會提供此 interface 中所有的 methods 的程式碼
Object-Oriented Programming (OOP) 如何將概念轉成程式碼 輪胎物件 class 輪胎 { 數量 = 1 個 胎紋 = 星狀 抓地力 = 好 處理法 { … } } 主程式物件 齒輪物件 class 腳踏車 { 輪胎處理好 齒輪處理好 煞車器處理好 在主機身上鎖上輪胎、 齒輪和煞車器即可 } class 齒輪 { 數量 = 1大, 2小 材質 = 不鏽鋼 齒量 = 24 齒 處理法 { … } } 煞車器物件 class 煞車器 { 數量 = 1 組 碟煞 = 是 處理法 { … } }
Object-Oriented Programming (OOP) 每個物件應該都有一些狀態(變數-variables)和功能(函數-methods) public class Bike{ int currentSpeed, currentGear, numberofGears; public int changeGears(int x) { … } public int brake() { … } …
物件基礎(Object Basics) 建立物件三步驟 宣告 Declaration 建構 Instantiation 語法:Class objName; 建構 Instantiation 使用 new 運算子建構新物件,此時將分配空間給此物件 初始化 Initialization 使用 new 運算子的同時,將呼叫類別建構元(constructor) 例01:String str = new String(“Hello World!”); 例02:String str; str = new String(“Hello World!”);
宣告暨實作一個Class的要點 分public和private部分 決定有哪些公開或私有的方法Method 決定有哪些公開或私有的屬性Property 宣告建構元(constructor)初始化類別的所有變數 class Cat { public int Age = 10; //有些屬性是公開的 private String animalType = “feline"; private String catColor; //有些屬性是私有的 Cat(String colorIn) // Cat 類別的建構元 {} public String getCatsColor() //Cat 提供的method {} public String getCatsType() {} }
建構 Instantiation 物件是參考資料型態(Reference Data Type) Bike myBike = new Bike(); myBike 0x5678 0x1234 0x5678 此物件實體 的變數、方 法
使用物件 物件單獨宣告時可暫時不需要建構與初始化(未分配記憶體空間);但在使用物件之前,一定得建構與初始化物件 使用物件的方式 -- 物件名稱後面加 . 加成員名稱 實體變數(instance variables) 語法:objName.varName 方法(methods) 語法:objName.methodName(argList) 例如:String s = new String(“Hello World!”); s.length(); // 取出 s 這個字串物件的長度 s.charAt(0); // 取出 s 這個字串物件第一個字元
補充: 系統對物件的清除 物件的清除 在某些物件導向程式語言中,要求當物件無用時,必須明確的將其刪除,否則將持續佔據記憶體空間 Java 程式語言中,會自動偵測無用的物件,並將之刪除,稱為垃圾收集(garbage collection),此機制由垃圾收集器(garbage collector)自動執行 無用的物件可直接指定為 null 語法:objName = null; 手動立即執行記憶體清除:System.gc(); 當物件被清除掉後,它會立刻呼叫物件的 finalize 方法,在大部分情況下,系統會自動處理
產生物件並使用物件 Example: ObjectDemo.java 規格書Test 用規格書Test建構物件 class Test { public int x; //instance variable int getX() { return x; } void printX() { System.out.println(x); void printMsg(String s) { System.out.println(s); void sayHello() { System.out.println("HelloWorld!!"); // 產生一個 testObj 物件 Test testObj = new Test(); // testObj 提供的 methods testObj.setX(500); testObj.printX(); testObj.printMsg("Java"); testObj.sayHello(); x = testObj.getX(); System.out.println("x = " + x); 用規格書Test建構物件
Your Turn class Cat { public int Age = 10; private String animalType = “feline"; private String catColor; Cat(String colorIn) // Cat 類別的建構元 { catColor = colorIn; } public String getCatsColor() //Cat 提供的method { return catColor; public String getCatsType() { return animalType; Your Turn 製作一個 Cat 的類別—寫Cat.java產生Cat.calss 以先前寫程式的習慣製作 CatDisplay.java 在main()方法中存取 Cat 中的屬性以及方法—獲得貓的年齡、顏色、種類並列印出來