ç¹¼‰èˆ‡¤‍‹ (Inheritance and Polymorphism)

  • View
    45

  • Download
    0

Embed Size (px)

DESCRIPTION

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

Text of ç¹¼‰èˆ‡¤‍‹ (Inheritance and...

  • (Inheritance and Polymorphism)//

  • protectedOCP:-0.1*

  • System.ObjectLSP: LiskovDIP: ISP: *

  • protectedOCP:-0.1

  • 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;}

  • 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;. . .

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

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

  • UML

  • 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}

  • A a = new A();B b = new B();C c = new C();data1data2data1data2data3abdata1data2data3data1data4c

  • protectedOCP:-0.1

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

  • UsingProtected.Programclass 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 ); } }

  • protectedOCP:-0.1

  • sealed class SClass {. . . . . .}

  • protectedOCP:-0.1

  • 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();

  • 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; }}

  • 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;}}

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

  • Primate human = new Primate( 4 );public Primate( int n ) : base( "Primate" ){ . . .

    }public Animal( string s ){ . . . }

  • UsingConstructorsForInheritance

  • protectedOCP:-0.1

  • -(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

  • OCPViolationExample

  • 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);

  • 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; } }}

  • 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");}

  • 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; }}

  • 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; }}

  • OCPViolationExampleShape()switchShapeenumswitchProgramDraw

  • protectedOCP:-0.1

  • (packaging)(inheritance)(polymorphism)

  • (compile-time binding)(run-time binding)(static binding)(dynamic binding)(virtual)(override)

  • DrawingAllShapes

  • 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());

  • 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);

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

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

  • 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"); }}

  • 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"); }}

  • DrawingAllShapesTriangle

  • protectedOCP:-0.1

  • BlackJack_0_1

  • 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();

  • 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);}

  • 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();}

  • 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(); }

  • BlackJack_0_1.Game (3/6) // for (i=0; i < N_PLAYERS; ++i) { players[i].SaveACard( deck.DealACard()); players[i].Dump(); }

  • BlackJack_0_1.Game (4/6) // for(i=0; i
  • BlackJack_0_1.Game (5/6) // Player dealer = players[N_PLAYERS-1]; for(i=0; i= players[i].GetTotalPoints()) { Console.WriteLine( dealer.Name + ""+players[i].Name); } else { Console.WriteLine( players[i].Name+""+dealer.Name); } }}

  • BlackJack_0_1.Game (6/6)private bool IsBlackJackOrBurst( Player player) { bool isBlackJack = false; if (player.GetStatus()==Status.BLACK_JACK) { isBlackJack = true; Console.WriteLine(player.Name+ " BlackJack!!!"); } bool isBurst = false; if (player.GetStatus() == Status.BURST){ isBurst = true; Console.WriteLine(player.Name+" !!!"); } return (isBlackJack || isBurst); }

  • BlackJack_0_1.Player (1/5)private Card[] hand = new Card[11];private int nCards;private Status status;private int totalPoints;private string name;public Player(){ nCards = 0; name = "";}

  • BlackJack_0_1.Player (2/5)public Player(string name){ nCards = 0; this.name = name;}public string Name{ get { return name; }}

  • BlackJack_0_1.Player (3/5)virtual public bool WantOneMoreCard(){ Console.Write("? (y/n) "); string answer = Console.ReadLine(); return (answer == "Y" || answer == "y");}

  • BlackJack_0_1.Player (4/5)public void Dump(){ int i; Console.Write(name+" : "); for (i = 0; i < nCards; ++i) { hand[i].Dump(); Console.Write("\t"); if ((i + 1) % 5 == 0) Console.WriteLine(); }

  • BlackJack_0_1.Player (5/5) Console.WriteLine(); Console.WriteLine(name + " : " + totalPoints);}

  • BlackJack_0_1.Dealerclass Dealer : Player { public Dealer() : base("") {} override public bool WantOneMoreCard() { return (base.GetTotalPoints() < 17); }}

  • protectedOCP:-0.1

  • UsingBase.Program

  • UsingBase.Program (1/3)// Define the base classclass Car{ public virtual void DescribeCar() { System.Console.WriteLine( "Four wheels and an engine."); }}

  • UsingBase