Introduction to Computer Science

Download Report

Transcript Introduction to Computer Science

類別與方法
(Classes and Methods)
鄭士康
國立台灣大學
電機工程學系/電信工程研究所/
資訊網路與多媒體研究所
1
程式 UsingObject (1/2)
using System;
namespace UsingObject
{
class Program
{
/* 示範類別的宣告與物件的使用
* 3/17/2007
*/
static void Main(string[] args)
{
Hello hello = new Hello();
hello.showMessage();
Console.WriteLine(hello.accessMessage);
hello.accessMessage = "測試訊息";
hello.showMessage();
2
程式 UsingObject (2/2)
Console.ReadLine();
}
}
public class Hello
{
string message = "Hello! 原始測試訊息";
public void showMessage()
{
Console.WriteLine(message);
}
public string accessMessage
{
get { return message; }
set { message = value; }
}
}
}
3
類別(Class)觀念
類別 File
資料變數(欄位成員 field)
fileName
方法函式(函式成員 function)
Open()
Read()
Create() Write()
Delete()
4
物件(Object)觀念
file1
file1.fileName
記憶體地址1
函式Open進入地址
file2
file2.fileName
記憶體地址2
函式Open進入地址
函式成員Open進入點
5
程式 CalculatorTest (1/6)
using System;
namespace CalculatorTest
{
/* 測試類別Calculator以說明函式的使用
* 3/17/2007
*/
class Program
{
static void Main(string[] args)
{
int op = 0;
int operand1;
int operand2;
int result;
Calulator calculator = new Calulator();
6
程式 CalculatorTest (2/6)
do
{
Console.Write(
"指定運算: 0. 結束; 1. 加; 2. 減; 3. 乘; 4. 除: ");
op = int.Parse(Console.ReadLine());
if (op == 0) break;
if (op > 4) continue;
Console.Write("輸入第一個數字: ");
operand1 = int.Parse(Console.ReadLine());
Console.Write("輸入第二個數字: ");
operand2 = int.Parse(Console.ReadLine());
switch (op)
{
7
程式 CalculatorTest (3/6)
case 1:
result = calculator.Add(operand1,
operand2);
Console.WriteLine("{0} + {1} = {2} ",
operand1, operand2, result);
break;
case 2:
result = calculator.Subtract(operand1,
operand2);
Console.WriteLine("{0} - {1} = {2} ",
operand1, operand2, result);
break;
case 3:
result = calculator.Multiply(operand1,
operand2);
8
程式 CalculatorTest (4/6)
Console.WriteLine("{0} * {1} = {2} ",
operand1, operand2, result);
break;
case 4:
result = calculator.Divide(operand1,
operand2);
Console.WriteLine("{0} / {1} = {2} ",
operand1, operand2, result);
break;
default:
Console.WriteLine(
"Should not appear this message. Debug!!!");
break;
}
} while (true);
}
}
9
程式 CalculatorTest (5/6)
/*
* 計算器
* 3/17/2007
*/
public class Calulator
{
public int Add(int a, int b)
{
int result = a + b;
return result;
}
public int Subtract(int a, int b)
{
int result = a - b;
return result;
}
10
程式 CalculatorTest (6/6)
public int Multiply(int a, int b)
{
int result = a * b;
return result;
}
public int Divide(int a, int b)
{
int result = a / b;
return result;
}
}
}
11
函式傳回值
Program.Main()
result
calculator.Add()
result
return value
12
程式 PassByReferenceAndOut (1/4)
using System;
namespace PassByReferenceAndOut
{
/*
* 示範傳址參數與out參數的使用方法
* 3/17/2007
*/
class Program
{
static void Main(string[] args)
{
double length = 100.0;
Square s = new Square();
s.acessLength = length;
13
程式 PassByReferenceAndOut (2/4)
double area1 = 0.0;
double perimeter1 = 0.0;
s.getAreaAndPerimeter(ref area1,
ref perimeter1);
Console.WriteLine(
"正方形邊長: {0}, 面積: {1}, 周長: {2}",
length, area1, perimeter1);
double area2;
double perimeter2;
s.getAreaAndPerimeterUsingOut(out area2,
out perimeter2);
Console.WriteLine(
"正方形邊長: {0}, 面積: {1}, 周長: {2}",
length, area2, perimeter2);
Console.ReadLine();
}
}
14
程式 PassByReferenceAndOut (3/4)
/*
* 正方形
* 3/17/2007
*/
public class Square
{
double a;
public double acessLength
{
get { return a; }
set { a = value; }
}
15
程式 PassByReferenceAndOut (4/4)
public void getAreaAndPerimeter(ref double area,
ref double perimeter)
{
area = Math.Pow(a, 2);
perimeter = 4.0 * a;
}
public void getAreaAndPerimeterUsingOut(
out double area, out double perimeter)
{
area = Math.Pow(a, 2);
perimeter = 4.0 * a;
}
}
}
16
傳值, 傳址, out 參數
• 傳值參數傳遞( Pass by value )
• 傳址參數傳遞( Pass by reference )
• out 參數
– 初值設定問題
17
程式 UsingThis (1/4)
using System;
namespace UsingThis
{
/*
* 說明this的使用
* 3/17/2007
*/
class Program
{
static void Main(string[] args)
{
Time t = new Time();
t.SetTime(11, 30, 52);
18
程式 UsingThis (2/4)
int hour;
int min;
int sec;
t.GetTime(out hour, out min, out sec);
Console.WriteLine("現在時間{0} : {1} : {2}",
hour, min, sec);
Console.ReadLine();
}
}
/*
* 以時,分,秒表示時間
*/
19
程式 UsingThis (3/4)
public class Time
{
int hour;
int min;
int sec;
public void SetTime(int hour, int
{
bool error = ( hour < 0 || hour
min < 0 || min >
sec < 0 || sec >
if (!error)
{
this.hour = hour;
this.min = min;
this.sec = sec;
}
min, int sec)
> 24 ||
59 ||
59 );
20
程式 UsingThis (4/4)
else
{
Console.WriteLine(
"Time.SetTime>>參數值不合理");
}
}
public void GetTime(out int hour, out int min,
out int sec)
{
hour = this.hour;
min = this.min;
sec = this.sec;
}
}
21
物件自我參考 this
t
記憶體地址
hour
min
sec
this
SetTime()進入地址
函式成員SetTime進入點
22
UML 的類別符號
Time
hour : int
min : int
sec : int
SetTime()
GetTime()
23
程式 OverloadingDemo (1/4)
using System;
namespace OverloadingDemo
{
/*
* 示範多載之應用
* 3/17/2007
*/
class Program
{
static void Main(string[] args)
{
Adder adder = new Adder();
int i = 0;
24
程式 OverloadingDemo (2/4)
do
{
Console.Write(
"指定運算數值型態: 0. 結束; 1. 整數; 2. 浮點數: ");
i = int.Parse(Console.ReadLine());
if (i == 0) break;
if (i > 2) continue;
switch (i)
{
case 1:
Console.Write("輸入第一個整數");
int a = int.Parse(Console.ReadLine());
Console.Write("輸入第二個整數");
int b = int.Parse(Console.ReadLine());
adder.AddAndDisplay(a, b);
break;
25
程式 OverloadingDemo (3/4)
case 2:
Console.Write("輸入第一個浮點數");
double ad =
double.Parse(Console.ReadLine());
Console.Write("輸入第二個浮點數");
double bd =
double.Parse(Console.ReadLine());
adder.AddAndDisplay(ad, bd);
break;
}
} while (true);
}
}
/* 模擬加法器
* 3/17/2007
*/
26
程式 OverloadingDemo (4/4)
public class Adder
{
public void AddAndDisplay(int a,
{
int result = a + b;
Console.WriteLine("{0} + {1} =
result);
}
public void AddAndDisplay(double
{
double result = a + b;
Console.WriteLine("{0} + {1} =
result);
}
}
int b)
{2}", a, b,
a, double b)
{2}", a, b,
}
27
程式 UsingRecursive (1/4)
using System;
namespace UsingRecursive
{
/*
* 利用階乘說明遞迴函式的用法
* 3/17/2007
*
* 測試:
* 以遞迴及非遞迴兩種方式計算!, 結果應相同
*/
class Program
{
static void Main(string[] args)
{
28
程式 UsingRecursive (2/4)
int factorialNonRecursive =
FactorialNonRecursive(10);
int factorialRecursive =
FactorialRecursive(10);
Console.WriteLine("(迴圈) 10! = " +
factorialNonRecursive);
Console.WriteLine("(遞迴) 10! = " +
factorialNonRecursive);
}
/*
* 不用遞迴計算階乘
* 3/17/2007
*/
29
程式 UsingRecursive (3/4)
static int FactorialNonRecursive(int n)
{
int result = 1;
for (int i = 1; i <= n; i++)
{
result *= i;
}
return result;
}
/*
* 利用遞迴計算階乘
* 3/17/2007
*/
30
程式 UsingRecursive (4/4)
static int FactorialRecursive(int n)
{
if (n == 1 || n == 0) return 1;
int result = n * FactorialRecursive(n - 1);
return result;
}
}
}
31
遞迴的觀念
32
二分搜尋法 (Binary Search)
Alice
Bob
Carol
David
Elaine
Fred
George
Harry
Irene
John
Kelly
Larry
Mary
Nancy
Oliver
Harry
Irene
John
Kelly
Larry
Mary
Nancy
Oliver
Irene
John
Kelly
33
二分搜尋法虛擬碼
*J. G. Brookshear, Computer Science – An Overview, 8th edition,
Addison-Wesley, 2005
34
類別 NameList
NameList
list : string[]
min : int
sec : int
AccessList()
Search()
35
極端化程式設計
(Extreme Programming)
1.
2.
3.
4.
5.
撰寫一個簡單的測試程式
編譯執行程式,看它失敗
增添恰能通過測試之程式碼並編譯偵錯
重整及消除冗餘程式碼並編譯偵錯
反覆進行上述步驟
36
程式 BinarySearch.Program (1/4)
using System;
namespace BinarySearch
{
/* 實作二分搜尋法
* skj 3/20/2007
*
* 測試規劃
*
* 名單:
* 0: Abe
* 1: Bob
* 2: Carol'
* 3: David
* 4: Eve
*
37
程式 BinarySearch.Program (2/4)
* target: Carol ==> 第3名
* target: Bob
==> 第2名
* target: Abe
==> 第1名
* target: David ==> 第4名
* target: Eve
==> 第5名
* target: Mary ==> 不在名單中
* target: Aaron ==> 不在名單中
* target: Brown ==> 不在名單中
*/
class Program
{
static void Main(string[] args)
{
38
程式 BinarySearch.Program (3/4)
string[] list = new string[5];
list[0] = "Abe";
list[1] = "Bob";
list[2] = "Carol";
list[3] = "David";
list[4] = "Eve";
NameList nameList = new NameList();
nameList.AccessList = list;
int index;
Console.Write("輸入欲搜尋的名字: ");
string target = Console.ReadLine();
bool success = nameList.Search(target, 0, 4,
out index);
39
程式 BinarySearch.Program (4/4)
if (success)
{
Console.WriteLine(target + "為名單中的第" +
(index + 1) + "名");
}
else
{
Console.WriteLine(target + "不在名單中");
}
}
}
}
40
程式 BinarySearch.NameList (1/3)
using System;
namespace BinarySearch
{
/*
* 排序好的名單類別
* skj 3/20/2007
*/
class NameList
{
string[] list; // 儲存之名單
public string[] AccessList
{
get { return list; }
set { list = value; }
}
41
程式 BinarySearch.NameList (2/3)
/*
* 檢查字串target是否在list之中
* 3/20/2007
*/
public bool Search(string target,// 欲搜尋之字串
int low,
// 檢查註標之下限
int high,
// 檢查註標之上限
out int index // 最後檢查的註標
)
{
index = (low + high) / 2;
if (low > high ) return false;
int result = target.CompareTo(list[index]);
42
程式 BinarySearch.NameList (3/3)
if (result == 0)
{
return true;
}
else if (result < 0)
{
high = index - 1;
return Search(target, low, high, out index);
}
else
{
low = index + 1;
return Search(target, low, high, out index);
}
}
}
}
43
物件導向思維
• 什麼是程式要完成的功能?
• 需要那些物件/類別才能完成程式功
能?
• 物件/類別需要那些行為才能合作完
成程式功能?
• 例: Mission Impossible, RPG
44
物件/類別之識別
• 程式功能敘述中的名詞、代名詞、名詞
片語可能需要轉換為物件/類別(CRC卡)
• 程式功能敘述中的動詞、動詞片語可能
需要轉換為物件/類別的方法(CRC卡)
• 需要相同方法的物件可以歸納出一個類
別(CRC卡)
• 類別之間的關係可以畫UML類別圖表示
• 主程式及類別的方法可以用虛擬碼進一
步描述
45
物件 CRC 卡
Object Name: withdrawManager Collaborators
Responsibilities
Ask user for amount to withdraw
Verify amount with
AccountManager
accountManager
cashDispenser
Tell cash dispenser to release
cash
46
類別 CRC卡
Class Name: WithdrawManager
Collaborators
Responsibilities
Ask user for amount to withdraw
AccountManager
Verify amount with
AccountManager
CashDispenser
Tell CashDispenser to release
cash
47
UML 類別圖( Class Diagram )
* G. Booch, J. Rumbaugh, and I. Jacobson, The Unified Modeling Language
User Guide, Addison Wesley, 1999.
48
構成(Aggregation)之實作
class Company {
//……
Department[] department;
// created by Company objects
Office[] office;
// created by Company objects
//……
}
49
關連(Association)之實作
class Department {
//……
Person manager; // created outside Department
Person[] member; // created outside Department
//……
}
class Person {
//……
Department department; // created outside Person
//……
}
50