1 / 47

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

類別與物件 II (Classes and Objects II). 鄭士康 國立台灣大學 電機工程學系 / 電信工程研究所 / 資訊網路與多媒體研究所. 程式 DiceSimulation.Program (1/3). using System; namespace DiceSimulation { /* * 模擬擲骰子示範類別的宣告與物件的使用 * 使用類別 Dice 的建構 函式 * 3/23/2008 */ class Program {

ownah
Download Presentation

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

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. 類別與物件 II(Classes and Objects II) 鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所

  2. 程式 DiceSimulation.Program (1/3) using System; namespace DiceSimulation { /* * 模擬擲骰子示範類別的宣告與物件的使用 * 使用類別Dice的建構函式 * 3/23/2008 */ class Program { static void Main(string[] args) {

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

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

  5. 程式 DiceSimulation.Dice (1/2) using System; namespace DiceSimulation { /* * 骰子 * 3/23/2008 */ public class Dice { int faceValue; Random rand; public Dice() { rand = new Random(); Toss(); }

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

  7. 建構函式與解構函式(Constructor and Destructor) • 預設建構函式(default constructor) • 具參數之建構函式 • 檢驗參數範圍 • 解構函式

  8. 物件產生與消滅流程 static void main( string[] arg ) { public Dice(int seed) { . . . } Dice dice = new Dice( seed ); 物件宣告 物件生成 ~Dice() { . . . } } 刪除物件dice 離開主函數, 程式結束

  9. 存取修飾詞(Access Modifiers) • public • private • protected • internal

  10. 練習 • 修改類別Card,改用建構函式設定初值,以屬性取得suit及faceValue Card suit : char faceValue : int Suit FaceValue

  11. 程式 UsingStatic.Program (1/2) using System; namespace UsingStatic { /* 示範靜態成員之使用 * 3/27/2007 */ class Program { static void Main(string[] args) { Console.WriteLine( "請輸入要轉換的小時數與天數, 以一個空格分開"); string[] input = (Console.ReadLine()).Split(' '); int hours = int.Parse(input[0]); int days = int.Parse(input[1]);

  12. 程式 UsingStatic.Program (2/2) int hoursToMins = TimeConversion.HoursToMins(hours); int daysToHours = TimeConversion.DaysToHours(days); Console.WriteLine(hours + " hours = " + hoursToMins + " minutes"); Console.WriteLine(days + " days = " + daysToHours + " hours"); Test t1 = new Test(); Test t2 = new Test(); Console.WriteLine(Test.GetNConstructed + " Test objects were constructed"); Console.ReadLine(); } } }

  13. 程式 UsingStatic.TimeConversion (1/2) using System; namespace UsingStatic { /* * collection of time conversion routines * 3/27/2007 */ public static class TimeConversion { private const int HOURS_PER_DAY = 24; private const int MINS_PER_HOUR = 60;

  14. 程式 UsingStatic.TimeConversion (2/2) public static int HoursToMins( int hours ) { return hours*MINS_PER_HOUR; } public static int DaysToHours( int days ) { return days*HOURS_PER_DAY; } } }

  15. 程式 UsingStatic.Test using System; namespace UsingStatic { public class Test { private static int nConstructed = 0; public Test(){ ++nConstructed; } public static int GetNConstructed{ get{ return nConstructed; } } } }

  16. 靜態成員與靜態類別 • 常數宣告 • 靜態成員應用場合 • 靜態函式Main • 靜態類別應用場合

  17. 靜態成員的記憶配置 t1 記憶體地址1 函式Test()進入地址 t2 函式Test()進入地址 記憶體地址2 函式成員Test進入點 Test nConstructed 記憶體地址 函式成員 GetNConstructed進入點

  18. 練習 (1/2) • 在類別Card內增加靜態成員函式,累計產生的Card物件數 • 寫一程式利用類別Card產生全副撲克牌,放在陣列deck內

  19. 練習 (2/2) • 實作並測試一靜態類別EqSolver,內含兩靜態成員函式double Linear(double a, double b)及double Quadratic(double a, double b, double c)分別解一次方程式a x + b = 0及a x2 + b x + c = 0

  20. 運算子多載 • 可以多載 • 一元:+、-、!、~、++、--、true、false • 二元:+、-、*、/、%、&、|、^、<<、>>、==、!=、>、<、>=、<= • 不可多載 • =、.、&&、||、?:、[] 、() 、->、new、is、sizeof、typeof、+=、-=、*=、/=、%=、&=、|=、^=、<<=、>>= • 轉換運算子 • explicit 關鍵字 • Implicit 關鍵字

  21. UsingOperOverload.Program(1/2) using System; namespace UsingOperOverload { /* 示範一元運算子多載 * 4/9/2007 */ class Program { static void Main(string[] args) { Rectangle rec = new Rectangle(100, 50); Console.WriteLine("長方形rec的面積: " + rec.Area());

  22. UsingOperOverload.Program(2/2) rec++; Console.WriteLine("長方形rec++後的面積: " + rec.Area()); // 應為 5151 ++rec; Console.WriteLine("長方形++rec後的面積: " + rec.Area()); // 應為 5304 Console.ReadLine(); } } }

  23. UsingOperOverload.Rectangle(1/2) using System; namespace UsingOperOverload { public class Rectangle { private int width; private int length; private int area; public Rectangle(int width, int length) { this.width = width; this.length = length; area = width * length; }

  24. UsingOperOverload.Rectangle(2/2) public int Area() { return area; } public static Rectangle operator ++(Rectangle op) { Rectangle result = new Rectangle(op.width+1, op.length+1); return result; } } }

  25. UsingOperOverload2.Program(1/2) using System; namespace UsingOperOverload2 { /* * 示範二元運算子多載的應用 * 4/9/2007 */ class Program { static void Main(string[] args) { Rectangle rec1 = new Rectangle(100, 50); Rectangle rec2 = new Rectangle(90, 25); Rectangle recSum = rec1 + rec2; Rectangle recDif = rec1 - rec2;

  26. UsingOperOverload2.Program(2/2) // recSum.Area() 應為14250 Console.WriteLine("rec1 + rec2 的面積: " + recSum.Area()); // recDif.Area() 應為250 Console.WriteLine("rec1 - rec2 的面積: " + recDif.Area()); Console.ReadLine(); } } }

  27. UsingOperOverload2.Rectangle(1/2) using System; namespace UsingOperOverload2 { class Rectangle { private int width; private int length; private int area; public Rectangle(int width, int length) { this.width = width; this.length = length; area = width * length; }

  28. UsingOperOverload2.Rectangle(2/2) public int Area() {return area;} public static Rectangle operator +(Rectangle op1, Rectangle op2){ Rectangle result = new Rectangle( op1.width + op2.width, op1.length + op2.length); return result; } public static Rectangle operator -(Rectangle op1, Rectangle op2){ Rectangle result = new Rectangle( op1.width - op2.width, op1.length - op2.length); return result; } } }

  29. 運算子執行流程 Rectangle recSum = rec1 + rec2; public static Rectangle operator+(Rectangle op1, Rectangle op2){ Rectangle result = new Rectangle( op1.width + op2.width, op1.length + op2.length); return result; }

  30. 練習 • 撰寫測試主程式及類別Rational(有理數),其中須測試及定義有理數+、-、*、/、++運算子。可不必考慮約分。

  31. RelOperOverload.Program(1/2) using System; namespace RelOperOverload { /* * 示範關聯運算子>和<的多載 * 4/11/2007 */ class Program { static void Main(string[] args) { StudentClass clsA = new StudentClass(20); StudentClass clsB = new StudentClass(30); bool clsAIsLarger = clsA > clsB; string message = clsAIsLarger ? "A班人數大於B班" : "A班人數不大於B班";

  32. RelOperOverload.Program(2/2) Console.WriteLine(message); Console.ReadLine(); } } }

  33. RelOperOverload.StudentClass(1/3) using System; namespace RelOperOverload { public class StudentClass { private int nStudents; public StudentClass(int nStudents) { if (nStudents < 0) { this.nStudents = 0; } else { this.nStudents = nStudents; } }

  34. RelOperOverload.StudentClass(2/3) public int accessNStudents { get { return nStudents; } } public static bool operator >(StudentClass op1, StudentClass op2) { bool result = (op1.nStudents > op2.nStudents); return result; }

  35. RelOperOverload.StudentClass(3/3) public static bool operator <(StudentClass op1, StudentClass op2) { bool result = (op1.nStudents < op2.nStudents); return result; } } }

  36. 練習 • 在類別Rational(有理數)中添加有理數>、<、!(檢驗是否為0)運算子,並予測試。 • 處理Rational(有理數)類別與整數進行+、-、*、/的情形

  37. RelOperOverload2.Program(1/2) using System; namespace RelOperOverload2 { /* * 示範關聯運算子==,!=,Equals,GetHashCode等的多載 * 4/11/2007 */ class Program { static void Main(string[] args) { StudentClass clsA = new StudentClass("A", 20); StudentClass clsB = new StudentClass("B", 20); bool clsAEqualsclsB = clsA == clsB; string message = clsAEqualsclsB ? “clsA與clsB相等”: “clsA與clsB不等";

  38. RelOperOverload2.Program(2/2) Console.WriteLine(message); clsAEqualsclsB = clsA.Equals(clsB); message = clsAEqualsclsB ? “clsA與clsB相等": “clsA與clsB不等"; Console.WriteLine(message); Console.ReadLine(); } } }

  39. RelOperOverload2.StudentClass(1/3) using System; namespace RelOperOverload2 { public class StudentClass { private int nStudents; private string name; public StudentClass(string name, int nStudents) { this.name = name; if (nStudents < 0) { this.nStudents = 0; }

  40. RelOperOverload2.StudentClass(2/3) else { this.nStudents = nStudents; } } public static bool operator ==(StudentClass op1, StudentClass op2) { bool result = ( op1.name.Equals(op2.name) ) && (op1.nStudents == op2.nStudents); return result; } public static bool operator !=(StudentClass op1, StudentClass op2) { return !(op1 == op2); }

  41. RelOperOverload2.StudentClass(3/3) public override bool Equals(object obj) { bool result = false; if (obj is StudentClass){ StudentClass op = (StudentClass) obj; result = name.Equals(op.name) && (nStudents == op.nStudents); } return result; } public override int GetHashCode(){ return nStudents.GetHashCode() + name.GetHashCode(); } } }

  42. ConvertOper.Program (1/2) using System; namespace ConvertOper { /* * 示範explicit與implicit的轉換 * 4/11/2007 */ class Program { static void Main(string[] args) { Rectangle rec = new Rectangle(15, 10); int area = (int) rec; Console.WriteLine("rec面積為" + area); Square sq = new Square(20);

  43. ConvertOper.Program (2/2) rec = sq; area = (int)rec; Console.WriteLine("sq面積為" + area); Console.ReadLine(); } } }

  44. ConvertOper.Rectangle (1/2) using System; namespace ConverOper { public class Rectangle { int width; int length; int area; public Rectangle(int width, int length) { this.width = width; this.length = length; area = length * width; }

  45. ConvertOper.Rectangle (2/2) public static explicit operator int(Rectangle op) { return op.area; } } }

  46. ConvertOper.Square using System; namespace ConvertOper { public class Square{ private int width; public Square(int width){ this.width = width; } public static implicit operator Rectangle( Square op ) { Rectangle rec = new Rectangle( op.width, op.width ); return rec; } } }

  47. 練習 • 在類別Rational(有理數)中添加有理數==、!=運算子及Equals、GetHashCode方法,並予測試。 • 在類別Rational(有理數)中添加轉為double的explicit運算子,及int轉為Rational的implicit運算子

More Related