物件与类别.ppt

上传人:本田雅阁 文档编号:2842647 上传时间:2019-05-26 格式:PPT 页数:119 大小:648.55KB
返回 下载 相关 举报
物件与类别.ppt_第1页
第1页 / 共119页
物件与类别.ppt_第2页
第2页 / 共119页
物件与类别.ppt_第3页
第3页 / 共119页
物件与类别.ppt_第4页
第4页 / 共119页
物件与类别.ppt_第5页
第5页 / 共119页
点击查看更多>>
资源描述

《物件与类别.ppt》由会员分享,可在线阅读,更多相关《物件与类别.ppt(119页珍藏版)》请在三一文库上搜索。

1、1,物件與類別,鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所,2,綱要,由函式到類別 屬性 函式成員之多載 建構式與解構式 this 參考 靜態成員 結構 複製建構式 物件作為函式參數 物件陣列,3,綱要,由函式到類別 屬性 函式成員之多載 建構式與解構式 this 參考 靜態成員 結構 複製建構式 物件作為函式參數 物件陣列,4,三個矩形物件,a,b,c,3,5,2,2,4,1,5,旋轉90o,a,b,c,3,5,2,2,4,1,6,RotatingRectangles0.Program.Main片段,/ 矩形a int width_a = 3; int he

2、ight_a = 5; / 矩形b int width_b = 2; int height_b = 2; / 矩形c int width_c = 4; int height_c = 1; / 旋轉90度 Rotate(ref width_a, ref height_a); Rotate(ref width_b, ref height_b); Rotate(ref width_c, ref height_c);,7,RotatingRectangles0.Program.Rotate,static void Rotate(ref int width, ref int height) int te

3、mp = width; width = height; height = temp; ,8,討論,矩形a的寬與高,分開宣告為width_a與height_a 靠註解才能知道它們屬於同一個矩形 旋轉90o應該是矩形物件具有的功能,在程式中卻完全看不出來 單看程式碼很難體會它代表將矩形旋轉90o 使用幾乎沒有限制 即使兩個參數並不代表某個矩形物件的寬與高,任何程式師還是可以透過呼叫函式Rotate,來交換任兩個整數變數的數值,9,矩形物件列表,10,旋轉90o後矩形物件列表,11,矩形類別,12,C# Class Rectangle,class Rectangle public int width

4、; public int height; public void Rotate() int temp = width; width = height; height = temp; ,13,物件、類別,物件(Object) 狀態與功能:例如, 矩形a, 電視機甲 類別(Class) 藍圖:例如, 矩形類別, 泛稱電視機 狀態:成員變數(member variables) 如width, height 功能:成員函式(member function) 如Rotate,14,類別Rectangle之成員函式Rotate,功能為交換封裝一起的成員變數width和height之值 不需要由外界輸入參數

5、 不用加上關鍵字static,15,RotatingRectangles.Program.Main 片段,Rectangle a = new Rectangle(); a.width = 3; a.height = 5; Rectangle b = new Rectangle(); b.width = 2; b.height = 2; Rectangle c = new Rectangle(); c.width = 4; c.height = 1; a.Rotate(); b.Rotate(); c.Rotate();,16,新增類別程式,專案加入類別類別 輸入類別名稱.cs,17,Rotat

6、ingRectangles.Rectangle 框架程式碼,using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace RotatingRectangles class Rectangle ,18,封裝(Encapsulation),類別將狀態變數與功能函式封裝起來 使類別內容的修改更容易 若能把類別變成黑箱(black box)模組,使用的程式師不用了解成員變數與成員函式的細節,就能應用類別的功能 程式碼重複使用(code reuse) 函式導向的程式也可將函式

7、當作黑箱模組 相關的變數沒有結合在一起 程式碼重複使用不是那麼方便,19,堆疊(Stack)與堆積(Heap),Stack,. . .,20,實值型別儲存方式,堆疊(Stack),int x = 100;,100,x,21,參考型別儲存方式,堆疊(Stack),string x = “abc”;,x,參考,a,b,c,堆積(Heap),22,矩形物件記憶配置,23,成員函式,同類別的物件,同一個成員函式只有一套函式程式碼 各物件就只存放這個程式碼進入點的位置 函式程式碼通常佔據相當大的記憶,如果每個物件都存放一套函式程式碼,需要很多記憶體 不同物件呼叫自己的成員函式,使用物件自己的成員變數 會

8、把物件在堆積記憶區的地址(稱為this)也傳給成員函式 由this成員函式可知道如何取用對應的成員變數,24,private與public,一般電視機 可以讓一般使用者調整的按鈕通常顯露在外 不讓使用者碰觸的電路裝置,都封裝在機殼內,對使用者來說無異黑箱 類別 相當於電視內部電路,作為自身工具幫手的成員變數與成員函式,宣告時加上關鍵字private,不讓外界程式師取用 像是電視的操控按鈕,提供給外界使用的成員變數與成員函式,則在宣告時加上關鍵字public 視為進一步的封裝,25,軟體IC,硬體IC 內部的電路封裝在內,不輕易顯露 電子電路工程師應用IC時,只要在接腳施加正確的電壓電流訊號,I

9、C便能正常工作,大大減輕電子電路工程師的負擔 類別的封裝 軟體工程師不需要了解private成員變數與成員函式 只要懂得public成員的使用,也能正確應用既有類別程式,達到減輕工作負荷,增進效率的目的,26,封裝,通常狀態變數為private ,只供同類別之功能函式取用,不可以由類別外直接取用 若有必要讓外界取得或設定其值,通常另外再寫public的成員函式來處理避開同名變數問題 避免被不慎改動,破壞狀態的正確一致性 容易維護,不影響外界程式 功能函式可能公用(public) ,也可能私有 一類別至少有一公用函式,以便應用,27,RotatingRectangles2.Rectangle片段

10、 (1/2),private int width; private int height; public void SetWidth( int w ) width = w; public int GetWidth() return width; public void SetHeight(int h) height = h; ,28,RotatingRectangles2.Rectangle片段 (2/2),public int GetHeight() return height; public void Rotate() int temp = width; width = height; h

11、eight = temp; ,29,RotatingRectangles2.Program.Main片段 (1/2),Rectangle a = new Rectangle(); a.SetWidth(3); a.SetHeight(5); Rectangle b = new Rectangle(); b.SetWidth(2); b.SetHeight(2); Rectangle c = new Rectangle(); c.SetWidth(4); c.SetHeight(1); a.Rotate(); b.Rotate(); c.Rotate();,30,RotatingRectangl

12、es2.Program.Main片段 (2/2),Debug.Assert(a.GetWidth() = 5 ,31,偵錯器追踪,物件的成員變數值 逐步執行或按F11鍵,至進入類別 目前類別名稱、函式名稱 函式區域變數及參數 this及物件的成員變數值,32,綱要,由函式到類別 屬性 函式成員之多載 建構式與解構式 this 參考 靜態成員 結構 複製建構式 物件作為函式參數 物件陣列,33,設定或取得成員變數的值,通常將成員變數宣告為private,另外宣告public的成員函式來設定或取得成員變數的值,以維護成員變數間的一致性 類別中增加了很多只是要Set和Get成員變數值的簡單函式,使類

13、別宣告有一點冗長,而呼叫這些函式時也得加上括弧,有一點累贅,34,屬性 (Attribute),兼顧成員變數間的一致與程式寫法的簡潔 成員函式SetWidth和GetWidth可以整合為一個屬性Width,成員函式SetHeight和GetHeight可以整合為一個屬性Height 將屬性名稱取成與成員變數相同 唯一差別為開始字母之大小寫 屬性名稱也可以與成員變數不同 此處的作法可以省去找新名稱的麻煩,並使屬性與成員變數的關連清楚,35,RotatingRectangles3.Program.Main片段 (1/2),Rectangle a = new Rectangle(); a.Width

14、 = 3; a.Height = 5; Rectangle b = new Rectangle(); b.Width = 2; b.Height = 2; Rectangle c = new Rectangle(); c.Width = 4; c.Height = 1; a.Rotate(); b.Rotate(); c.Rotate();,36,RotatingRectangles3.Program.Main片段 (2/2),Debug.Assert(a.Width = 5 ,37,RotatingRectangles3.Rectangle片段,private int width; priv

15、ate int height; public int Width set width = value; get return width; public int Height set height = value; get return height; ,38,DiceSimulation.Program.Main片段,int count = 0, 0, 0, 0, 0, 0 ; int N = 12000; Dice dice = new Dice(); for (int i = 0; i N; +i) dice.Toss(); countdice.FaceValue - 1+; for (

16、int k = 0; k 6; +k) Console.WriteLine(“ 0 appears 1 times “, k + 1, countk); ,39,DiceSimulation.Dice,class Dice private int faceValue = 1; private Random rand = new Random(); public int FaceValue get return faceValue; public void Toss() faceValue = rand.Next() % 6 + 1; ,40,投擲兩顆骰子,Dice dice1 = new Di

17、ce(); Dice dice2 = new Dice(); dice1.Toss(); dice2.Toss(); Console.WriteLine( dice1.FaceValue ); Console.WriteLine( dice2.FaceValue ); 非常可能發現兩顆骰子擲出的結果相同 dice1和dice2幾乎同時建立 成員變數rand建立時,會使用相同的計算機時間做為亂數產生器的種子,使兩者得到的亂數數列完全相同,41,綱要,由函式到類別 屬性 函式成員之多載 建構式與解構式 this 參考 靜態成員 結構 複製建構式 物件作為函式參數 物件陣列,42,函式多載 (Ove

18、rloading),變數、函式、物件、類別都要選擇適切的名稱,程式才易寫易讀 適當的名稱常常不夠應用 FORTRAN語言函式庫的例子 讓計算實數參數與複數參數正弦函數的函式,雖然演算法不同,都命名為SIN 計算機自動依照參數型別的不同來決定該呼叫那一個函式 C+、Java、C#採相似的做法,43,分辨類別的成員函式,主要靠函式名稱,其次是參數的個數與型別 名稱相同,但是參數的個數或型別有所不同時,就可認為是不同的函式 例:模擬時鐘運作 時間的呈現可以是二十四小時制,也可以是區分上下午(AM、PM)的十二小時制 如果設定時間(SetTime)與取得時間(GetTime)的函式,對兩種不同時間呈現

19、方式要取不同名稱,並不太容易,即使能夠,也會使函式名稱變得很長,不易使用,44,ClockSimulation.Program.Main片段,Clock c = new Clock(); c.SetTime(22, 40, 23); c.Tick(); c.GetTime(out h, out m, out s); Debug.Assert(h = 22 ,45,ClockSimulation.Program.Clock片段 (1/4),private int hour = 0; / 023 private int minute = 0;/ 059 private int second = 0

20、;/ 059 / 24小時制 public void SetTime( int h, int m, int s ) SetValues( h, m, s ); / 上下午制 public void SetTime( int h, int m, int s, string aAMPM ) SetValues( h, m, s ); if( aAMPM = “PM“ ,46,ClockSimulation.Program.Clock片段 (2/4),private void SetValues( int h, int m, int s ) hour = h; minute = m; second

21、= s; / 24小時制 public void GetTime(out int h, out int m, out int s) h = hour; m = minute; s = second; ,47,ClockSimulation.Program.Clock片段 (3/4),/ 上下午制 public void GetTime(out int h, out int m, out int s, out string aAMPM) h = hour; if (hour 12) h -= 12; m = minute; s = second; if (hour = 12) aAMPM = “

22、PM“; else aAMPM = “AM“; ,48,ClockSimulation.Program.Clock片段 (4/4),/ 前進一秒 public void Tick() second+; if (second = 60) second = 0; minute+; if (minute = 60) minute = 0; hour+; if (hour = 24) hour = 0; ,49,綱要,由函式到類別 屬性 函式成員之多載 建構式與解構式 this 參考 靜態成員 結構 複製建構式 物件作為函式參數 物件陣列,50,初始值設定,建立物件後,必需以屬性或成員函式指定成員變數

23、的值 如果忘了,就發生錯誤 沒有設定成員變數初值的錯誤,通常稱為初始值未設定錯誤(initialization error) 最好在建立物件時便能設定必要成員變數的初值,51,RotatingRectangles4.Program.Main片段,Rectangle a = new Rectangle(3, 5); Rectangle b = new Rectangle(2); Rectangle c = new Rectangle(4, 1); a.Rotate(); b.Rotate(); c.Rotate(); Debug.Assert(a.Width = 5 ,52,RotatingRe

24、ctangles4.Rectangle片段 (1/2),private int width; private int height; public Rectangle() width = 1; height = 1; public Rectangle(int w, int h) width = w; height = h; public Rectangle(int w) width = w; height = w; ,53,RotatingRectangles4.Rectangle片段 (2/2),public int Width get return width; public int He

25、ight get return height; public void Rotate() int temp = width; width = height; height = temp; ,54,DiceSimulation2.Program.Main 片段,int count = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ; int N = 12000; const int SEED_1 = 168; Dice dice1 = new Dice(SEED_1); const int SEED_2 = 777; Dice dice2 = new Dice(SEED_2);

26、 for (int i = 0; i N; +i) dice1.Toss(); dice2.Toss(); count dice1.FaceValue + dice2.FaceValue - 2+; ,55,DiceSimulation2.Dice片段,private int faceValue = 1; private Random rand; public Dice() rand = new Random(); public Dice(int seed) rand = new Random(seed); public int FaceValue get return faceValue;

27、Dice() ,56,解構式 (Destructor),Dice() 與建構式相對,用於物件將被消滅的時候 會將物件佔用的堆積記憶區使用權歸還給系統,以便系統可以把這些記憶體分配給其他物件使用 稱為停用記憶區收集(garbage collection) 把不再使用的資源釋出 例如,某個處理檔案的物件,在建構式中開啟檔案,開始應用,當物件要被消滅時,便需在解構式中關閉檔案,以便他處可以再使用同一檔案,57,記憶漏失 (Memory Leakage),記憶區回收的工作可能相當複雜,處理不好,就容易有忘記回收的區域 忘記回收的區域逐漸累積,就可能使程式繼續執行所需的記憶體不足,稱為記憶漏失 先前的程

28、式語言如C+,經驗不足的程式設計師很容易就寫出有記憶漏失的程式碼 較新的語言如Java、C#通常讓系統自動回收記憶區,因此解構式內就不必再寫回收記憶區的程式敘述,58,解構式,可看成特別的成員函式 一個類別只能有一個解構式 必須能被外界呼叫,所以不可加上public或private等修飾語 沒有回傳值,所以也不宣告回傳值型別,59,物件產生與消滅流程,60,綱要,由函式到類別 屬性 函式成員之多載 建構式與解構式 this 參考 靜態成員 結構 複製建構式 物件作為函式參數 物件陣列,61,物件宣告,在堆疊記憶區指定一個位址 接著以建構式建立物件 在堆積記憶區配置成員變數 填入成員變數初值 將

29、堆積記憶區開始的位址放入堆疊記憶區的對應位置,成為物件的參考,62,this參考,堆疊記憶區有一個參考指到堆積記憶區 堆積記憶區通常也會存放一個參考 直接指到物件在堆積記憶區的開始位置 這個參考稱為this 成員函式呼叫時會將參考this一併傳出 以便成員函式可以使用對應物件的成員變數 或用同樣方式呼叫其他成員函式,63,Rectangle物件記憶配置,a,this,b,this,a.width,b.width,函式Rectangle.Rotate進入點,a.height,b.height,堆疊記憶區,堆積記憶區,64,參數名稱,在成員函式或建構式中可以特別用this指出物件本身的成員變數 參

30、數名稱便可以取成與成員變數名稱相同 在成員變數前加上this區分即可,65,RotatingRectangles5.Rectangle片段,private int width; private int height; public Rectangle(int width, int height) this.width = width; this.height = height; public Rectangle(int width) this.width = width; this.height = width; public int Width get return width; ,66,要

31、當心的情況 Rectangle.Scale,public void Scale(int s, int width, int height) width *= s; height *= s; . . . . . . Rectangle a = new Rectangle(3, 5); a.Scale(2, 3, 5);,67,綱要,由函式到類別 屬性 函式成員之多載 建構式與解構式 this 參考 靜態成員 結構 複製建構式 物件作為函式參數 物件陣列,68,不需物件的函式呼叫,例如兩個與時間轉換相關的函式HoursToMins和DaysToHours 分別把小時數換算成分鐘、天數換算成小時 H

32、oursToMins(5)為300(5小時等於300分鐘) DaysToHours(4)為96(4天等於96小時) 可以寫成主程式裏的函式,供主程式呼叫 這兩個函式就被綁在主程式裏,不容易給其他的類別程式使用,69,靜態成員函式,把函式連同它們要用到的常數,一起包在一個類別內 宣告時加註關鍵字static,表示是靜態成員函式,不會用到物件的成員變數 類別中宣告的常數不算成員變數 呼叫時,不需先建立物件,直接以類別名稱呼叫即可,70,ConvertingTime.TimeConversion,class TimeConversion private const int HOURS_PER_DAY

33、 = 24; private const int MINS_PER_HOUR = 60; public static int HoursToMins(int hours) return hours * MINS_PER_HOUR; public static int DaysToHours(int days) return days * HOURS_PER_DAY; ,71,ConvertingTime.Program.Main片段,Debug.Assert(TimeConversion.HoursToMins(5) = 300); Debug.Assert(TimeConversion.Da

34、ysToHours(4) = 96); Console.Write(“請輸入要轉換的小時數(整數): “); int hours = int.Parse(Console.ReadLine(); Console.Write(“請輸入要轉換的天數(整數): “); int days = int.Parse(Console.ReadLine(); int hoursToMins = TimeConversion.HoursToMins(hours); int daysToHours = TimeConversion.DaysToHours(days);,72,靜態成員函式,主程式Main的執行,並不

35、需要用到Program物件的成員變數 主程式Main必須宣告成類別Program的靜態成員函式 數學函數,如Exp、Log、Sin、Cos等,也都是系統類別Math的靜態成員函式 要以類別名稱Math呼叫,73,計算物件產生的個數,可以在主程式中放一個計數器,每建立一個物件就累加一次 如果主程式外的其他類別成員函式執行時,也會產生物件,主程式中的計數器就算不到這些另外建立的物件 物件計數器最好還是放在類別中 讓類別自己統計已建立的物件總數,74,CountingRectangles.Program.Main,static void Main(string args) Rectangle a =

36、 new Rectangle(3, 5); Rectangle b = new Rectangle(2); Rectangle c = new Rectangle(4, 1); Rectangle d = new Rectangle(); Debug.Assert( Rectangle.GetNConstructed() = 4); Debug.Assert(Rectangle.NRectangles = 4); ,75,CountingRectangles.Rectangle片段 (1/2),private int width; private int height; private sta

37、tic int nConstructed = 0; public Rectangle() width = 1; height = 1; nConstructed+; public Rectangle(int width, int height) this.width = width; this.height = height; nConstructed+; ,76,CountingRectangles.Rectangle片段 (2/2),public Rectangle(int width) this.width = width; this.height = width; nConstruct

38、ed+; public static int GetNConstructed() return nConstructed; public static int NRectangles get return nConstructed; ,77,Rectangle物件記憶配置,a,this,b,this,a.width,a.height,堆疊記憶區,堆積記憶區,Rectangle.nConstructed,函式Rectangle.GetNConstructed進入點,屬性Rectangle.NRectangles進入點,b.width,b.height,函式Rotate進入點,預設建構式進入點,建

39、構式1進入點,建構式2進入點,屬性Width進入點,屬性Height進入點,類別Rectangle成員函式,78,綱要,由函式到類別 屬性 函式成員之多載 建構式與解構式 this 參考 靜態成員 結構 複製建構式 物件作為函式參數 物件陣列,79,UsingStruct.Point2D,struct Point2D public int x; public int y; ,80,UsingStruct.Program.Main,static void Main(string args) Point2D pt = new Point2D(); Console.WriteLine( “Initi

40、al location = (0,1)“, pt.x, pt.y); pt.x = 3; pt.y = 4; Console.WriteLine( “Final location = (0,1)“, pt.x, pt.y); ,81,類別與結構的記憶配置,由類別產生的物件放一個參考在堆疊區 指到堆積記憶區的成員變數的開始位置 由結構建立的物件把所有的成員變數與成員函式進入點都存放在堆疊區,82,StructVSClass.SPoint2D,struct SPoint2D public int x; public int y; public SPoint2D(int x, int y) this

41、.x = x; this.y = y; ,83,StructVSClass.CPoint2D,class CPoint2D public int x; public int y; public CPoint2D() x = 0; y = 0; public CPoint2D(int x, int y) this.x = x; this.y = y; ,84,StructVSClass.Program.Main片段 (1/4),SPoint2D sPt1 = new SPoint2D(3, 4); SPoint2D sPt2 = new SPoint2D(); SPoint2D sPt3 = n

42、ew SPoint2D(); sPt2 = sPt1; sPt3 = sPt1; Console.WriteLine(“sPt1 = (0, 1)“, sPt1.x, sPt1.y); Console.WriteLine(“sPt2 = (0, 1)“, sPt2.x, sPt2.y); Console.WriteLine(“sPt3 = (0, 1)“, sPt3.x, sPt3.y);,85,StructVSClass.Program.Main片段 (2/4),CPoint2D cPt1 = new CPoint2D(3, 4); CPoint2D cPt2 = new CPoint2D(

43、); CPoint2D cPt3 = new CPoint2D(); cPt2 = cPt1; cPt3 = cPt1; Console.WriteLine(“cPt1 = (0, 1)“, cPt1.x, cPt1.y); Console.WriteLine(“cPt2 = (0, 1)“, cPt2.x, cPt2.y); Console.WriteLine(“cPt3 = (0, 1)“, cPt3.x, cPt3.y);,86,StructVSClass.Program.Main片段 (3/4),sPt1.x = 10; sPt1.y = 20; sPt2.x = 30; sPt2.y

44、 = 40; Console.WriteLine(“sPt1 = (0, 1)“, sPt1.x, sPt1.y); Console.WriteLine(“sPt2 = (0, 1)“, sPt2.x, sPt2.y); Console.WriteLine(“sPt3 = (0, 1)“, sPt3.x, sPt3.y);,87,StructVSClass.Program.Main片段 (4/4),cPt1.x = 10; cPt1.y = 20; cPt2.x = 30; cPt2.y = 40; Console.WriteLine(“cPt1 = (0, 1)“, cPt1.x, cPt1

45、.y); Console.WriteLine(“cPt2 = (0, 1)“, cPt2.x, cPt2.y); Console.WriteLine(“cPt3 = (0, 1)“, cPt3.x, cPt3.y);,88,結構物件記憶配置,sPt1,堆疊記憶區,sPt1.x,sPt2.y,sPt1.y,sPt2.x,sPt3.x,sPt3.y,this,this,this,建構式SPoint2D進入點,sPt2,sPt3,89,cPt2.x,類別物件記憶配置,cPt1,this,cPt2,this,cPt1.x,預設建構式CPoint2D進入點,cPt1.y,cPt2.y,堆疊記憶區,堆積記

46、憶區,cPt3.x,cPt3.y,cPt3,this,建構式CPoint2D進入點,90,練習,宣告並測試結構Student,其中包括學號、姓名、成績,91,綱要,由函式到類別 屬性 函式成員之多載 建構式與解構式 this 參考 靜態成員 結構 複製建構式 物件作為函式參數 物件陣列,92,類別物件設值,僅將堆疊記憶區的物件參考設成相同 而不改變成員變數之值 使原先不同的物件綁在一起,成為相同物件,容易產生語義錯誤 若程式有造成這種語義錯誤的可能,應該在設值時使用複製建構式(copy constructor),93,UsingCopyConstructor.Program.Main 片段 (

47、1/2),CPoint2D cPt1 = new CPoint2D(3, 4); CPoint2D cPt2 = new CPoint2D( cPt1 ); CPoint2D cPt3 = new CPoint2D( cPt1 ); Console.WriteLine(“cPt1 = (0, 1)“, cPt1.x, cPt1.y); Console.WriteLine(“cPt2 = (0, 1)“, cPt2.x, cPt2.y); Console.WriteLine(“cPt3 = (0, 1)“, cPt3.x, cPt3.y);,94,UsingCopyConstructor.Pro

48、gram.Main 片段 (2/2),cPt1.x = 10; cPt1.y = 20; cPt2.x = 30; cPt2.y = 40; Console.WriteLine(“cPt1 = (0, 1)“, cPt1.x, cPt1.y); Console.WriteLine(“cPt2 = (0, 1)“, cPt2.x, cPt2.y); Console.WriteLine(“cPt3 = (0, 1)“, cPt3.x, cPt3.y);,95,UsingCopyConstructor.CPoint2D片段,public CPoint2D() x = 0; y = 0; public CPoint2D(int x, int y) this

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 其他


经营许可证编号:宁ICP备18001539号-1