1 / 138

繼承與多型 (Inheritance and Polymorphism)

繼承與多型 (Inheritance and Polymorphism). 鄭士康 國立台灣大學 電機工程學系 / 電信工程研究所 / 資訊網路與多媒體研究所. 綱要. 繼承 修飾語 protected 限制繼承 繼承架構下的建構函式呼叫 OCP: 開放 - 封閉原理 多型 二十一點模擬程式 0.1 版 *覆寫與隱藏. 綱要. 預設類別 System.Object LSP: Liskov 替代性原理 抽象類別 DIP: 依存性反轉原理 介面 ISP: 介面分離原理 多重介面 *多重介面鑄形. 綱要. 繼承 修飾語 protected

sarah
Download Presentation

繼承與多型 (Inheritance and Polymorphism)

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. 繼承與多型(Inheritance and Polymorphism) 鄭士康 國立台灣大學 電機工程學系/電信工程研究所/ 資訊網路與多媒體研究所

  2. 綱要 • 繼承 • 修飾語protected • 限制繼承 • 繼承架構下的建構函式呼叫 • OCP:開放-封閉原理 • 多型 • 二十一點模擬程式0.1版 • *覆寫與隱藏

  3. 綱要 • 預設類別System.Object • LSP: Liskov替代性原理 • 抽象類別 • DIP: 依存性反轉原理 • 介面 • ISP: 介面分離原理 • 多重介面 • *多重介面鑄形

  4. 綱要 • 繼承 • 修飾語protected • 限制繼承 • 繼承架構下的建構函式呼叫 • OCP:開放-封閉原理 • 多型 • 二十一點模擬程式0.1版 • 覆寫與隱藏

  5. UsingInheritance.Calculator 片段 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; } public int Multiply(int a, int b) { int result = a * b; return result; }

  6. UsingInheritance.Program.Program.Main() 片段(1/2) AdvancedCalculator calculator = new AdvancedCalculator(); . . . switch (op) { case 1: result =calculator.Add(operand1,operand2); Console.WriteLine("{0} + {1} = {2} ", operand1, operand2, result); break; . . .

  7. UsingInheritance.Program.Program.Main() 片段(2/2) case 5: functionValue = calculator.GetSine(angle); Console.WriteLine( "Sine of {0} (deg) = {1}", angle, functionValue); break; . . . }

  8. UsingInheritance.AdvancedCalculator 片段 public class AdvancedCalculator : Calculator { public double GetSine(double angle) { angle *= Math.PI / 180.0; return Math.Sin(angle); } . . . }

  9. 表示繼承的UML類別圖

  10. A B C 類別繼承之階層關係 class A { private int data1; private int data2; //…other members are methods } class B : A { private int data3; //…other members are methods } class C : B { private int data1; private int data4; //…other members are methods }

  11. 物件記憶體分配模型 A a = new A(); B b = new B(); C c = new C(); data1 a data2 c data1 data1 b data2 data2 data3 data3 data1 data4

  12. 練習 • 實作並測試下列繼承關係

  13. 綱要 • 繼承 • 修飾語protected • 限制繼承 • 繼承架構下的建構函式呼叫 • OCP:開放-封閉原理 • 多型 • 二十一點模擬程式0.1版 • 覆寫與隱藏

  14. UsingProtected.Program.Program.Main()片段 DC d = new DC(); d.SetX(3); //Console.WriteLine( d.GetX() ) ; // Error! //d.x = 77; // Error! d.Add2();

  15. UsingProtected.Program片段 class BC { private int x; public void SetX( int x ) { this.x = x; } protected int GetX() { return x; } } class DC : BC { public void Add2() { int c = GetX(); SetX( c+2 ); } }

  16. 綱要 • 繼承 • 修飾語protected • 限制繼承 • 繼承架構下的建構函式呼叫 • OCP:開放-封閉原理 • 多型 • 二十一點模擬程式0.1版 • 覆寫與隱藏

  17. 限制繼承 sealed class SClass { . . . . . . }

  18. 綱要 • 繼承 • 修飾語protected • 限制繼承 • 繼承架構下的建構函式呼叫 • OCP:開放-封閉原理 • 多型 • 二十一點模擬程式0.1版 • 覆寫與隱藏

  19. UsingConstructorsForInheritance.Program.Main() 片段 Animal slug = new Animal(); Animal tweety = new Animal( "canary" ); Primate godzilla = new Primate(); Primate human = new Primate( 4 ); Human jill = new Human();

  20. UsingConstructorsForInheritance.Program 片段(1/3) class Animal { private string species; public Animal() { Console.WriteLine("Animal()"); species = "Animal"; } public Animal( string s ) { Console.WriteLine("Animal("+ s +")"); species = s; } }

  21. UsingConstructorsForInheritance.Program片段(2/3) class Primate : Animal { private int heartCham; public Primate() : base() { Console.WriteLine( "Primate()" ); } public Primate( int n ) : base( "Primate" ) { Console.WriteLine("Primate(" + n +")"); heartCham = n; } }

  22. UsingConstructorsForInheritance.Program 片段(3/3) class Human : Primate { public Human() : base( 4 ) { Console.WriteLine( "Human()" ); } }

  23. 衍生物件產生流程 Primate human = new Primate( 4 ); public Primate( int n ) : base( "Primate" ) { . . . } public Animal( string s ) { . . . }

  24. 練習 • 利用偵錯器體驗了解程式UsingConstructorsForInheritance

  25. 綱要 • 繼承 • 修飾語protected • 限制繼承 • 繼承架構下的建構函式呼叫 • OCP:開放-封閉原理 • 多型 • 二十一點模擬程式0.1版 • 覆寫與隱藏

  26. 開放-封閉原理(OCP:Open-Closed Principle) • Software entities (classes, modules, functions, etc.) should be open for extension, but closed for modification • 增添軟體單元新功能,但不影響此軟體單元的程式碼 *Robert C. Martin, Agile Software Development: Principles, Patterns, and Practices, Pearson Education, 2003

  27. 程式OCPViolationExample類別圖

  28. OCPViolationExample.Program.Program.Main() 片段 Point center; center.x = 15; center.y = 20; Point topLeft; topLeft.x = 30; topLeft.y = 40; Shape[] list = { new Circle(2, center), new Rectangle(3, 4, topLeft) }; DrawAllShapes(list);

  29. OCPViolationExample.Program.Program 片段 (1/2) static void DrawAllShapes(Shape[] list){ for (int i = 0; i < list.Length; ++i){ Shape s = list[i]; switch (s.type){ case ShapeType.CIRCLE: DrawCircle((Circle) s); break; case ShapeType.RECTANGLE: DrawRectangle((Rectangle) s); break; } } }

  30. OCPViolationExample.Program.Program 片段 (2/2) static void DrawCircle(Circle c) { Console.WriteLine("Draw a circle"); } static void DrawRectangle(Rectangle r) { Console.WriteLine("Draw a rectangle"); }

  31. OCPViolationExample.Program 片段 (1/2) class Shape { public ShapeType type; public Shape(ShapeType t){ type = t; } } class Circle : Shape{ private int radius; private Point center; public Circle(int radius, Point center) :base(ShapeType.CIRCLE){ this.radius = radius; this.center = center; } }

  32. OCPViolationExample.Program 片段 (2/2) class Rectangle : Shape { private int width; private int height; private Point topLeft; public Rectangle(int width, int height, Point topLeft): base(ShapeType.RECTANGLE) { this.width = width; this.height = height; this.topLeft = topLeft; } }

  33. OCPViolationExample的主要問題 • 添加任何有關Shape的演算(例如,拖曳、伸縮、移動、刪除)都要重複麻煩的switch敘述 • 增加一種新的Shape子類別,必須修改enum敘述、各處的switch敘述,並在類別Program增加對應的Draw函式

  34. 綱要 • 繼承 • 修飾語protected • 限制繼承 • 繼承架構下的建構函式呼叫 • OCP:開放-封閉原理 • 多型 • 二十一點模擬程式0.1版 • 覆寫與隱藏

  35. 物件導向的關鍵技術 • 封裝(packaging) • 繼承(inheritance) • 多型(polymorphism)

  36. 多型 • 編譯時連結(compile-time binding)與執行時連結(run-time binding) • 靜態連結(static binding)與動態連結(dynamic binding) • 多型之要求 • 繼承階層體系 • 虛擬(virtual)與覆寫(override) • 基礎類別之參考 • 多型之優缺點

  37. DrawingAllShapes類別圖

  38. DrawingAllShapes.Program.Program.Main() 片段(1/2) Shape[] list = new Shape[2]; Point center; center.x = 15; center.y = 20; Point topLeft; topLeft.x = 30; topLeft.y = 40; Circle c = new Circle(2, center); Rectangle r = new Rectangle(3, 4,topLeft); Console.WriteLine("決定畫圖順序, 輸入"); Console.WriteLine("1: 圓形, 矩形"); Console.WriteLine("2: 矩形, 圓形"); int ans = int.Parse(Console.ReadLine());

  39. DrawingAllShapes.Program.Program.Main() 片段(2/2) switch (ans) { case 1: list[0] = c; list[1] = r; break; case 2: list[0] = r; list[1] = c; break; default: . . . } DrawAllShapes(list);

  40. DrawingAllShapes.Program.Program 片段 static void DrawAllShapes(Shape[] list) { int i; for (i = 0; i < list.Length; ++i) { list[i].Draw(); } }

  41. DrawingAllShapes.Program 片段(1/3) class Shape { public Shape() { } virtual public void Draw() { } }

  42. DrawingAllShapes.Program 片段(2/3) class Circle : Shape { private int radius; private Point center; public Circle(int radius, Point center) { this.radius = radius; this.center = center; } override public void Draw() { Console.WriteLine("Draw a circle"); } }

  43. DrawingAllShapes.Program 片段(3/3) class Rectangle : Shape{ private int width; private int height; private Point topLeft; public Rectangle(int width, int height, Point topLeft){ this.width = width; this.height = height; this.topLeft = topLeft; } override public void Draw(){ Console.WriteLine("Draw a rectangle"); } }

  44. 練習 • 在程式DrawingAllShapes增加類別Triangle,使程式也能畫出三角形。

  45. 綱要 • 繼承 • 修飾語protected • 限制繼承 • 繼承架構下的建構函式呼叫 • OCP:開放-封閉原理 • 多型 • 二十一點模擬程式0.1版 • 覆寫與隱藏

  46. BlackJack_0_1 類別圖

  47. BlackJack_0_1.BlackJackTest 片段(1/2) public static bool Scenario1_OK() { Card[] cards = { new Card(Suit.SPADE, 1), new Card(Suit.HEART, 11), new Card(Suit.DIAMOND, 10) }; Deck deck = new Deck(cards); Player player = new Player(); Dealer dealer = new Dealer();

  48. BlackJack_0_1.BlackJackTest 片段(2/2) player.SaveACard(deck.DealACard()); dealer.SaveACard(deck.DealACard()); player.SaveACard(deck.DealACard()); return( player.GetStatus() == Status.BLACK_JACK &&dealer.GetStatus() == Status.PASS); }

  49. BlackJack_0_1.Game 片段 (1/6) const int N_PLAYERS = 2; Deck deck; Player[] players = new Player[N_PLAYERS]; public Game() { players[0] = new Player("Jeng"); players[N_PLAYERS-1] = new Dealer(); }

  50. BlackJack_0_1.Game 片段 (2/6) private void Play() { int i; // 第一輪發牌 for (i = 0; i < N_PLAYERS; ++i) { players[i].SaveACard( deck.DealACard()); players[i].Dump(); }

More Related