類別與物件 I (Classes and Objects I)

Slides:



Advertisements
Similar presentations
系統分析與設計 楊子青 H-1 H 、物件導向技術 n 物件導向的基本概念 – 物件、類別 – 封裝、繼承 – 同名異式 ( 多型 ) 、超荷 ( 過載 ) n 物件導向分析與設計及塑模工具 n UML 塑模工具.
Advertisements

鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
第一章 資料結構導論 1-1 資料結構簡介 1-2 認識程式設計 1-3 演算法效能分析 1-4 物件導向程式設計與Java.
Ch02物件導向程式設計 物件導向系統分析與設計.
四資二甲 第三週作業 物件導向程式設計.
C#程序设计案例教程 第3章 程 序 结 构.
第一章 面向对象程序设计.
C#程序设计 10软件1、2班 王槐彬 计算机工程学院.
第二章 JAVA语言基础.
類別與物件 Class & Object.
第9章 面向对象方法学引论 9.1 面向对象方法学概述 9.2 面向对象的概念 9.3 面向对象建模 9.4 对象模型 9.5 动态模型
新世代計算機概論 第14章 程式語言.
第八章 类和对象.
第三章 控制结构.
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
C# 程式設計 第一部分 第1-4章 C# 程式設計 - 南華大學資管系.
程式設計實作.
C#程序设计 c# programming 泛型 C#程序设计课程组.
H、物件導向技術 物件導向的基本概念 物件、類別 封裝、繼承 同名異式(多型) 、超荷(過載) 物件導向分析與設計及塑模工具 UML塑模工具.
.NET 程式設計入門(使用 C#) 講師:鄧智鴻.
第二章 C# 基础知识.
第四章 在 C# 中实现 OOP 概念.
Derived Class 前言 衍生類別的定義 單一繼承 public, protected, 和 privated 基底類別
流程控制結構 4-1 流程控制與UML活動圖 4-2 程式區塊與主控台基本輸入 4-3 條件控制敘述 4-4 迴圈控制敘述 4-5 巢狀迴圈
程式敘述執行順序的轉移 控制與重複、方法 Lecturer:曾學文.
第3章 語法入門 第一個Java程式 文字模式下與程式互動 資料、運算 流程控制.
第三章 C#面向对象初级编程 面向对象得程序设计越来越受到编程人员的喜爱。类和对象是面向对象程序设计中的重要概念。封装性、继承性和多态性是面向对象的特点,本章旨在全面说明C#编写面向对象程序设计的方法。
软件建模精要 面向对象软件建模技术.
第2章回顾 标识符:不用记,动手 关键字:if, else, switch, for, while, do, break, continue, void, …… 局部变量和成员变量 ①变量作用域 ②内存布局 基本数据类型 ①4类8种 ②互相转换 流程控制语句 ①分支 if……else, switch.
授课老师:龚涛 信息科学与技术学院 2018年3月 教材: 《Visual C++程序员成长攻略》 《C++ Builder程序员成长攻略》
C#程序设计基础 $3 成员、变量和常量.
2 C++ 的基本語法和使用環境 親自撰寫和執行程式是學好程式語言的不二法門。本章藉由兩個簡單的程式,介紹C++ 程式的基本結構和開發環境,讓初學者能逐漸建立使用C++ 的信心。
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
第9章 多线程 王德俊 上海交通大学继续教育学院.
第9章 類別圖與物件圖 9-1 類別圖與物件圖的基礎 9-2 類別圖的符號 9-3 類別關係 9-4 物件圖 9-5 繪製類別圖與物件圖
第4章 物件導向分析與設計簡介 4-1 物件導向的軟體系統開發 4-2 物件導向分析與設計 4-3 UML的物件導向分析與設計
第三章 流程控制與例外處理 資訊教育研究室 製作 注意:本投影片僅供上課使用,非經同意,請勿散播或轉載。
C#面向对象程序设计 $7 继承和多态性.
視窗程式設計 (Windows Programming)
例外處理與 物件序列化(Exception Handling and Serialization of Objects)
檔案讀寫與例外處理 (File IO and Exception Handling)
面向对象的分析与设计 教学计划 研究生课程 主讲教师:邵维忠 助教: 朱彬,柳毅,尤朝,张磊,黄艺燕 2009年2月—7月
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
Java程序设计 第2章 基本数据类型及操作.
第六章 属性、索引器、委托和事件.
第三章 C# 基础知识.
第二章Java基本程序设计.
程式結構&語法.
C#程序设计基础 $3 成员、变量和常量.
類別與方法 (Classes and Methods)
第二章 Java基本语法 讲师:复凡.
第6章 面向对象开发的 分析与设计.
<编程达人入门课程> 本节内容 为什么要使用变量? 视频提供:昆山爱达人信息技术有限公司 官网地址: 联系QQ:
第二章 Java语法基础.
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
目标 流程控制 字符串处理 C# 的类和对象 C# 访问修饰符 C# 构造函数和析构函数.
第 3 章 类的基础部分 陈哲 副教授 南京航空航天大学 计算机科学与技术学院.
#include <iostream.h>
第二章 Java基本语法 讲师:复凡.
第6單元 6-1 類別的繼承 (Class Inheritance) 6-2 抽象類別 (Abstract Class)
PPT注意事项: 当前PPT课件文件必须和提供的源代码文件夹“代码”在同一目录中即不要移动文件夹“代码”的默认位置。
第2章 Java语言基础.
C#快速導讀 流程控制.
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
第二章 Java基础语法 北京传智播客教育
第二章 Java基本语法 讲师:复凡.
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所
Presentation transcript:

類別與物件 I (Classes and Objects I) 鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所

結構化程式設計/逐步細分法 序列/分支/迴圈 虛擬碼 Magic number 7 加減 2 逐層分解工作 函式 軟體危機

物件導向程式設計 (Object-Oriented Programming) 軟體IC/程式碼重覆使用( Code Reuse) 封裝(Encapsulation) 狀態、行為 模擬 繼承(Inheritance) 多型(Polymorphism)

程式 DiceSimulation (1/4) using System; namespace DiceSimulation { /* * 模擬擲骰子示範類別的宣告與物件的使用 * 3/16/2008 * * 測試規畫: * 六個點數出現次數應該大約相同 */ class Program static void Main(string[] args)

程式 DiceSimulation (2/4) int[] count = new int[6]; // 累計點數出現次數 for (int i = 0; i < 6; ++i) { count[i] = 0; } const int N = 12000; // 總擲骰次數 int faceValue; Dice dice = new Dice(); // 擲骰N次 for (int i = 0; i < N; ++i) dice.Toss(); faceValue = dice.FaceValue; ++count[faceValue-1];

程式 DiceSimulation (3/4) // 印出結果 for (int i = 0; i < 6; ++i) { Console.WriteLine(" {0} appears {1} times ", i + 1, count[i]); }

程式 DiceSimulation (4/4) public class Dice { int faceValue = 1; Random rand = new Random(); public int FaceValue get { return faceValue; } set { faceValue = value; } } public void Toss() faceValue = rand.Next() % 6 + 1;

函式呼叫流程 static void Main(string[] args) { public class Dice { . . . public void Toss() faceValue = rand.Next() % 6 + 1; } dice.Toss(); } public class Random { . . . public int Next() }

類別(Class)觀念 類別 Dice 資料變數(欄位成員 field) faceValue, rand 方法函式(函式成員 function, 屬性 attribute) FaceValue Toss()

堆疊(Stack)與堆積(Heap) Heap . Stack

實值型別儲存方式 堆疊(Stack) int x = 100; x 100

參考型別儲存方式 堆積(Heap) 堆疊(Stack) string x = “abc”; x 參考 ‘a’ ‘b’ ‘c’

物件(Object)觀念 dice1 dice1.faceValue 記憶體地址1 dice1.rand 函式Toss進入地址 dice2 dice2.fileName 記憶體地址2 dice2.rand 函式Toss進入地址 函式成員Toss進入點

物件的設定(Assignment) dice2 = dice1; dice1 dice1.faceValue 記憶體地址1 dice1.rand 函式Toss進入地址 dice2 dice2 = dice1; dice2.fileName 記憶體地址2 dice2.rand 函式Toss進入地址 函式成員Toss進入點

UML 的類別符號 Dice faceValue : int rand: Random FaceValue Toss() : void

練習1 宣告並測試以下類別 Car speed : int driver : string Speed Driver Accelerate() PutOnBrakes()

程式 CalculatorTest (1/6) using System; namespace CalculatorTest { * 3/17/2007 */ class Program static void Main(string[] args) int op = 0; int operand1; int operand2; int result; Calulator calculator = new Calulator();

程式 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)

程式 CalculatorTest (3/6) case 1: result = calculator.Add(operand1, Console.WriteLine("{0} + {1} = {2} ", operand1, operand2, result); break; case 2: result = calculator.Subtract(operand1, Console.WriteLine("{0} - {1} = {2} ", case 3: result = calculator.Multiply(operand1,

程式 CalculatorTest (4/6) Console.WriteLine("{0} * {1} = {2} ", operand1, operand2, result); break; case 4: result = calculator.Divide(operand1, operand2); Console.WriteLine("{0} / {1} = {2} ", default: Console.WriteLine( "Should not appear this message. Debug!!!"); } } while (true);

程式 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;

程式 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;

函式傳回值 Program.Main() result calculator.Add() result return value

程式SwapIntegers (1/2) using System; namespace SwapIntegers { /* 交換兩個整數變數 * 以說明傳值呼叫與傳址呼叫 * skj 4/5/2008 */ class Program static void Main(string[] args) int x = 3; int y = 5; Console.WriteLine("x = {0}, y = {1}", x, y); Swap(ref x, ref y); }

程式SwapIntegers (2/2) static void Swap(ref int x, ref int y) { int temp = x; x = y; y = temp; }

程式 PassByReferenceAndOut (1/4) using System; namespace PassByReferenceAndOut { /* * 示範傳址參數與out參數的使用方法 * 3/31/2008 */ class Program static void Main(string[] args) double length = 100.0; Square s = new Square(); s.Side = length;

程式 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); "正方形邊長: {0}, 面積: {1}, 周長: {2}", length, area2, perimeter2); Console.ReadLine(); }

程式 PassByReferenceAndOut (3/4) /* * 正方形 * 3/16/2008 */ public class Square { double a; public double Side get { return a; } set { a = value; } }

程式 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)

傳值, 傳址, out 參數 傳值參數傳遞( Pass by value ) 傳址參數傳遞( Pass by reference ) 初值設定問題

類別Time Time hour : int min : int sec : int SetTime() GetTime()

程式 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);

程式 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(); } /* * 以時,分,秒表示時間 */

程式 UsingThis (3/4) public class Time { int hour; int min; int sec; public void SetTime(int hour, int min, int sec) bool error = ( hour < 0 || hour > 24 || min < 0 || min > 59 || sec < 0 || sec > 59 ); if (!error) this.hour = hour; this.min = min; this.sec = sec; }

程式 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;

物件自我參考 this t 記憶體地址 hour min sec this SetTime()進入地址 函式成員SetTime進入點

極端化程式設計 (Extreme Programming) 撰寫一個簡單的測試程式 編譯執行程式,看它失敗 增添恰能通過測試之程式碼並編譯偵錯 重整及消除冗餘程式碼並編譯偵錯 反覆進行上述步驟

練習(1/4) 寫主程式 以傳值參數參照下一頁虛擬碼,寫一個函式Swap交換兩張牌位置 宣告陣列 Card[] deck = new Card[2] 在deck中放入兩張撲克牌Card物件 呼叫函數Swap交換兩張牌位置 以傳值參數參照下一頁虛擬碼,寫一個函式Swap交換兩張牌位置

練習(2/4) 函式Swap虛擬碼 Procedure Swap( card1, card2 ) 1. temp = card1; return card1 temp card2

練習(3/4) 宣告並實作以下類別 Card suit : char faceValue : int SetCard() GetCard()

練習(4/4) 根據完成之Card類別修正主程式 測試兩張牌能否交換 將Swap函式之參數改為傳址參數,再試一次 利用偵錯器找出結果差異之原因

程式 OverloadingDemo (1/4) using System; namespace OverloadingDemo { /* * 示範多載之應用 * 3/17/2007 */ class Program static void Main(string[] args) Adder adder = new Adder(); int i = 0;

程式 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;

程式 OverloadingDemo (3/4) case 2: Console.Write("輸入第一個浮點數"); double ad = double.Parse(Console.ReadLine()); Console.Write("輸入第二個浮點數"); double bd = adder.AddAndDisplay(ad, bd); break; } } while (true); /* 模擬加法器 * 3/17/2007 */

程式 OverloadingDemo (4/4) public class Adder { public void AddAndDisplay(int a, int b) int result = a + b; Console.WriteLine("{0} + {1} = {2}", a, b, result); } public void AddAndDisplay(double a, double b) double result = a + b; Console.WriteLine("{0} + {1} = {2}", a, b, result);

物件導向思維 什麼是程式要完成的功能? 需要那些物件/類別才能完成程式功能? 物件/類別需要那些行為才能合作完成程式功能? 例: Mission Impossible, RPG

範例問題 假設有一N_ROW列、N_COL欄的整數表格,寫一程式計算每列總和、每欄總和、及全部總和。以如下2列3欄表格為例: 其每列總和為 9、18,每欄總和為8、11、8,全部總和為27。利用一個二維陣列儲存表格資料,兩個一維陣列分別儲存每列總和及每欄總和。 3 4 2 5 7 6

演算法主要虛擬碼 1. 取得資料 2. 計算每列總和 3. 計算每欄總和 4. 計算全部總和 5. 輸出答案

物件識別 表格 計算全部總和 列 計算全列之和 欄 計算全欄之和

類別 Table Table content: int[, ] nRow : int nCol : int Content GetRowSum() GetColSum() GetTotalSum()

程式 ClassDemo.Program (1/5) using System; namespace ClassDemo { /* * 假設有一N_ROW列、N_COL欄的整數表格, * 計算每列總和、每欄總和、及全部總和 * 利用物件導向 * * 主要虛擬碼: * 1. 取得資料 * 2. 計算每列總和 * 3. 計算每欄總和 * 4. 計算全部總和 * 5. 輸出答案

程式 ClassDemo.Program (2/5) * 測試: 2 X 3 表格 * +---------+---------+---------+ * | 3 | 4 | 2 | * | 5 | 7 | 6 | * * 每列總和 * +---------+---------+ * | 9 | 18 | * 每欄總和 * | 8 | 11 | 8 |

程式 ClassDemo.Program (3/5) * 全部總和 * 27 * */ class Program { static void Main(string[] args) const int N_ROW = 2; const int N_COL = 3; int[,] table = new int[N_ROW, N_COL]; table[0, 0] = 3; table[0, 1] = 4; table[0, 2] = 2; table[1, 0] = 5;

程式 ClassDemo.Program (4/5) table[1, 1] = 7; table[1, 2] = 6; Table t = new Table(); t.Content = table; int[] rowSum = t.GetRowSum(); int[] colSum = t.GetColSum(); int totalSum = t.GetTotalSum(); for (int i = 0; i < N_ROW; ++i) { Console.WriteLine("Sum of row " + i + " is " + rowSum[i]); }

程式 ClassDemo.Program (5/5) for (int j = 0; j < N_COL; ++j) { Console.WriteLine("Sum of column " + j + " is " + colSum[j]); } Console.WriteLine("Total sum is " + totalSum); Console.ReadLine();

程式 ClassDemo.Table (1/5) using System; namespace ClassDemo { /* * 表格 * skj 3/31/2008 */ public class Table private int[,] content; int nRow; int nCol;

程式 ClassDemo.Table (2/5) public int[,] Content { get { return content; } set content = value; nRow = content.GetUpperBound(0) + 1; nCol = content.GetUpperBound(1) + 1; }

程式 ClassDemo.Table (3/5) { int[] rowSum = new int[nRow]; public int[] GetRowSum() { int[] rowSum = new int[nRow]; for (int i = 0; i < nRow; ++i) rowSum[i] = 0; for (int j = 0; j < nCol; ++j) rowSum[i] += content[i, j]; } return rowSum;

程式 ClassDemo.Table (4/5) public int[] GetColSum() { int[] colSum = new int[nCol]; for (int j = 0; j < nCol; ++j) colSum[j] = 0; for (int i = 0; i < nRow; ++i) colSum[j] += content[i, j]; } return colSum;

程式 ClassDemo.Table (5/5) public int GetTotalSum() { int totalSum = 0; for (int i = 0; i < nRow; ++i) for (int j = 0; j < nCol; ++j) totalSum += content[i, j]; } return totalSum;

物件/類別之識別 程式功能敘述中的名詞、代名詞、名詞片語可能需要轉換為物件/類別(CRC卡) 類別之間的關係可以畫UML類別圖表示 主程式及類別的方法可以用虛擬碼進一步描述

物件 CRC 卡 Object Name: withdrawManager Collaborators Responsibilities Ask user for amount to withdraw Verify amount with AccountManager Tell cash dispenser to release cash accountManager cashDispenser

類別 CRC卡 Class Name: WithdrawManager Collaborators Responsibilities Ask user for amount to withdraw Verify amount with AccountManager Tell CashDispenser to release cash AccountManager CashDispenser

UML 類別圖( Class Diagram ) * G. Booch, J. Rumbaugh, and I. Jacobson, The Unified Modeling Language User Guide, Addison Wesley, 1999.

構成(Aggregation)之實作 class Company { //…… Department[] department; // created by Company objects Office[] office; }

關連(Association)之實作 class Department { //…… Person manager; // created outside Department Person[] member; // created outside Department } class Person { Department department; // created outside Person

延伸閱讀:系統分析與設計 F. P. Brooks, Jr., The Mythical Man-Month – Essays on Software Engineering, Addison-Wesley, 1975 G. Booch, J. Rumbaugh, and I. Jacobson, The Unified Modeling Language User Guide, Addison Wesley, 1999. I. Jacobson, G. Booch, and J. Rumbaugh, The Unified Software Development Process, Addison Wesley, 1999. R. C. Lee and W. M. Tepfenhart, UML and C++, A Practical Guide to Object-Oriented Development, 2nd ed., Prentice Hall, 2001. 李潛瑞譯, W. C. Wake 原著, 極端軟體製程--探索篇, 碁峰, 2002.

練習 (1/2) 模擬兩輛車的直線賽道競速比賽, 先擬好測試規畫 track1 track2

練習 (2/2) 主程式虛擬碼 while(true) { 擲骰子決定兩部車的加減速或維持速率; 計算各車前進距離(等於速率乘以時間); 更新兩部車在賽道上的位置; if 有車衝過終點, 記下駕駛員; break; } 印出勝利者姓名;