Using Inheritance Calculator public int Addint a int





Using. Inheritance. Calculator 片 public int Add(int a, 段 int b) { int result = a + b; return result; } public int Subtract(int { int result = a - b; return result; } public int Multiply(int { int result = a * b; return result; } a, int b) 5

Using. Inheritance. Program. Main() 片段(1/2) Advanced. Calculator calculator = new Advanced. Calculator(); . . . switch (op) { case 1: result = calculator. Add(operand 1, operand 2); Console. Write. Line("{0} + {1} = {2} ", operand 1, operand 2, result); break; . . . 6

Using. Inheritance. Program. Main() 片段(2/2) case 5: function. Value = calculator. Get. Sine(angle); Console. Write. Line( "Sine of {0} (deg) = {1}", angle, function. Value); break; . . . } 7

Using. Inheritance. Advanced. Calculator 片段 public class Advanced. Calculator : Calculator { public double Get. Sine(double angle) { angle *= Math. PI / 180. 0; return Math. Sin(angle); }. . . } 8


類別繼承之階層關係 class A { private int data 1; private int data 2; //…other members are methods } class B : A { private int data 3; //…other members are methods } class C : B { private int data 1; private int data 4; //…other members are methods } A B C 10

物件記憶體分配模型 A a = new A(); B b = new B(); C c = new C(); a data 1 data 2 c b data 1 data 2 data 3 data 1 data 4 11



Using. Protected. Program. Main()片段 DC d = new DC(); d. Set. X(3); //Console. Write. Line( d. Get. X() ) ; //d. x = 77; // Error! d. Add 2(); // Error! 14

Using. Protected. Program片段 class BC { private int x; public void Set. X( int x ) { this. x = x; } protected int Get. X() { return x; } } class DC : BC { public void Add 2() { int c = Get. X(); Set. X( c+2 ); } } 15


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


Using. Constructors. For. Inheritanc e. Program. Main () 片段 Animal slug = new Animal(); Animal tweety = new Animal( "canary" ); Primate godzilla = new Primate(); Primate human = new Primate( 4 ); Human jill = new Human(); 19

Using. Constructors. For. Inheritance. Program class Animal 片段 (1/3) { private string species; public Animal() { Console. Write. Line("Animal()"); species = "Animal"; } public Animal( string s ) { Console. Write. Line("Animal("+ s +")"); species = s; } } 20

Using. Constructors. For. Inheritanc e. Program class Primate : 片段 Animal (2/3) { private int heart. Cham; public Primate() : base() { Console. Write. Line( "Primate()" ); } public Primate( int n ) : base( "Primate" ) { Console. Write. Line("Primate(" + n +")"); heart. Cham = n; } } 21

Using. Constructors. For. Inheritanc e. Program 片段 (3/3) class Human : Primate { public Human() : base( 4 ) { Console. Write. Line( "Human()" ); } } 22

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

練習 • 利用偵錯器體驗了解程式 Using. Constructors. For. Inheritance 24


開放-封閉原理 (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 26

程式OCPViolation. Example類別圖 27

OCPViolation. Example. Program. Main() 片段 Point center; center. x = 15; center. y = 20; Point top. Left; top. Left. x = 30; top. Left. y = 40; Shape[] list = { new Circle(2, center), new Rectangle(3, 4, top. Left) }; Draw. All. Shapes(list); 28
![OCPViolation. Example. Program 片段 (1/2) static void Draw. All. Shapes(Shape[] list) { for (int OCPViolation. Example. Program 片段 (1/2) static void Draw. All. Shapes(Shape[] list) { for (int](http://slidetodoc.com/presentation_image_h/146e6ebd046fd6f9a2cdebe4a59c2235/image-29.jpg)
OCPViolation. Example. Program 片段 (1/2) static void Draw. All. Shapes(Shape[] list) { for (int i = 0; i < list. Length; ++i) { Shape s = list[i]; switch (s. type) { case Shape. Type. CIRCLE: Draw. Circle((Circle) s); break; case Shape. Type. RECTANGLE: Draw. Rectangle((Rectangle) s); break; } } } 29

OCPViolation. Example. Program 片段 (2/2) static void Draw. Circle(Circle c) { Console. Write. Line("Draw a circle"); } static void Draw. Rectangle(Rectangle r) { Console. Write. Line("Draw a rectangle"); } 30

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

OCPViolation. Example. Program 片段 (2/2) class Rectangle : Shape { private int width; private int height; private Point top. Left; public Rectangle(int width, int height, Point top. Left) : base(Shape. Type. RECTANGLE) { this. width = width; this. height = height; this. top. Left = top. Left; } } 32



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


Drawing. All. Shapes類別圖 37
![Drawing. All. Shapes. Program. Main() 片段(1/2) Shape[] list = new Shape[2]; Point center; center. Drawing. All. Shapes. Program. Main() 片段(1/2) Shape[] list = new Shape[2]; Point center; center.](http://slidetodoc.com/presentation_image_h/146e6ebd046fd6f9a2cdebe4a59c2235/image-38.jpg)
Drawing. All. Shapes. Program. Main() 片段(1/2) Shape[] list = new Shape[2]; Point center; center. x = 15; center. y = 20; Point top. Left; top. Left. x = 30; top. Left. y = 40; Circle c = new Circle(2, center); Rectangle r = new Rectangle(3, 4, top. Left); Console. Write. Line("決定畫圖順序, 輸入"); Console. Write. Line("1: 圓形, 矩形"); Console. Write. Line("2: 矩形, 圓形"); int ans = int. Parse(Console. Read. Line()); 38
![Drawing. All. Shapes. Program. Main () 片段 (2/2) switch (ans) { case 1: list[0] Drawing. All. Shapes. Program. Main () 片段 (2/2) switch (ans) { case 1: list[0]](http://slidetodoc.com/presentation_image_h/146e6ebd046fd6f9a2cdebe4a59c2235/image-39.jpg)
Drawing. All. Shapes. Program. Main () 片段 (2/2) switch (ans) { case 1: list[0] list[1] break; case 2: list[0] list[1] break; default: . . . = c; = r; = c; } Draw. All. Shapes(list); 39
![Drawing. All. Shapes. Program 片段 static void Draw. All. Shapes(Shape[] list) { int i; Drawing. All. Shapes. Program 片段 static void Draw. All. Shapes(Shape[] list) { int i;](http://slidetodoc.com/presentation_image_h/146e6ebd046fd6f9a2cdebe4a59c2235/image-40.jpg)
Drawing. All. Shapes. Program 片段 static void Draw. All. Shapes(Shape[] list) { int i; for (i = 0; i < list. Length; ++i) { list[i]. Draw(); } } 40

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

Drawing. All. Shapes. 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. Write. Line("Draw a circle"); } } 42

Drawing. All. Shapes. Program 片段(3/3) class Rectangle : Shape { private int width; private int height; private Point top. Left; public Rectangle(int width, Point top. Left) { this. width = width; this. height = height; this. top. Left = top. Left; } override public void Draw() Console. Write. Line("Draw a } } int height, { rectangle"); 43



Black. Jack_0_1 類別圖 46
![Black. Jack_0_1. Black. Jack. Test 片段(1/2) public static bool Scenario 1_OK() { Card[] cards Black. Jack_0_1. Black. Jack. Test 片段(1/2) public static bool Scenario 1_OK() { Card[] cards](http://slidetodoc.com/presentation_image_h/146e6ebd046fd6f9a2cdebe4a59c2235/image-47.jpg)
Black. Jack_0_1. Black. Jack. Test 片段(1/2) public static bool Scenario 1_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(); 47

Black. Jack_0_1. Black. Jack. Test 片段(2/2) player. Save. ACard(deck. Deal. ACard()); dealer. Save. ACard(deck. Deal. ACard()); player. Save. ACard(deck. Deal. ACard()); return( player. Get. Status() == Status. BLACK_JACK && dealer. Get. Status() == Status. PASS); } 48
![Black. Jack_0_1. Game 片段 (1/6) const int N_PLAYERS = 2; Deck deck; Player[] players Black. Jack_0_1. Game 片段 (1/6) const int N_PLAYERS = 2; Deck deck; Player[] players](http://slidetodoc.com/presentation_image_h/146e6ebd046fd6f9a2cdebe4a59c2235/image-49.jpg)
Black. Jack_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(); } 49

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

Black. Jack_0_1. Game 片段 (3/6) // 第二輪發牌 for (i=0; i < N_PLAYERS; ++i) { players[i]. Save. ACard( deck. Deal. ACard()); players[i]. Dump(); } 51
![Black. Jack_0_1. Game 片段 (4/6) // 開始要牌計牌 for(i=0; i<N_PLAYERS; ++i) { while (players[i]. Get. Black. Jack_0_1. Game 片段 (4/6) // 開始要牌計牌 for(i=0; i<N_PLAYERS; ++i) { while (players[i]. Get.](http://slidetodoc.com/presentation_image_h/146e6ebd046fd6f9a2cdebe4a59c2235/image-52.jpg)
Black. Jack_0_1. Game 片段 (4/6) // 開始要牌計牌 for(i=0; i<N_PLAYERS; ++i) { while (players[i]. Get. Status() == Status. PASS && players[i]. Want. One. More. Card() && deck. Has. More. Card()) { players[i]. Save. ACard(deck. Deal. ACard()); players[i]. Dump(); if(Is. Black. Jack. Or. Burst(players[i])) return; } } 52
![Black. Jack_0_1. Game 片段 (5/6) // 計點分勝負 Player dealer = players[N_PLAYERS-1]; for(i=0; i<N_PLAYERS-1; ++i) Black. Jack_0_1. Game 片段 (5/6) // 計點分勝負 Player dealer = players[N_PLAYERS-1]; for(i=0; i<N_PLAYERS-1; ++i)](http://slidetodoc.com/presentation_image_h/146e6ebd046fd6f9a2cdebe4a59c2235/image-53.jpg)
Black. Jack_0_1. Game 片段 (5/6) // 計點分勝負 Player dealer = players[N_PLAYERS-1]; for(i=0; i<N_PLAYERS-1; ++i) { if (dealer. Get. Total. Points() >= players[i]. Get. Total. Points()) { Console. Write. Line( dealer. Name + "勝"+players[i]. Name); } else { Console. Write. Line( players[i]. Name+"勝"+dealer. Name); } } } 53

Black. Jack_0_1. Game 片段 (6/6) private bool Is. Black. Jack. Or. Burst( Player player) { bool is. Black. Jack = false; if (player. Get. Status()==Status. BLACK_JACK) { is. Black. Jack = true; Console. Write. Line(player. Name+ " Black. Jack!!!"); } bool is. Burst = false; if (player. Get. Status() == Status. BURST){ is. Burst = true; Console. Write. Line(player. Name+" 爆!!!"); } return (is. Black. Jack || is. Burst); 54 }
![Black. Jack_0_1. Player 片段(1/5) private Card[] hand = new Card[11]; private int n. Cards; Black. Jack_0_1. Player 片段(1/5) private Card[] hand = new Card[11]; private int n. Cards;](http://slidetodoc.com/presentation_image_h/146e6ebd046fd6f9a2cdebe4a59c2235/image-55.jpg)
Black. Jack_0_1. Player 片段(1/5) private Card[] hand = new Card[11]; private int n. Cards; private Status status; private int total. Points; private string name; public Player() { n. Cards = 0; name = "無名氏"; } 55

Black. Jack_0_1. Player 片段(2/5) public Player(string name) { n. Cards = 0; this. name = name; } public string Name { get { return name; } } 56

Black. Jack_0_1. Player 片段(3/5) virtual public bool Want. One. More. Card() { Console. Write("要再一張牌嗎? (y/n) "); string answer = Console. Read. Line(); return (answer == "Y" || answer == "y"); } 57

Black. Jack_0_1. Player 片段(4/5) public void Dump() { int i; Console. Write(name+" 牌: "); for (i = 0; i < n. Cards; ++i) { hand[i]. Dump(); Console. Write("t"); if ((i + 1) % 5 == 0) Console. Write. Line(); } 58

Black. Jack_0_1. Player 片段(5/5) Console. Write. Line(); Console. Write. Line(name + " 總點數: " + total. Points); } 59

Black. Jack_0_1. Dealer片段 class Dealer : Player { public Dealer() : base("莊家") {} override public bool Want. One. More. Card() { return (base. Get. Total. Points() < 17); } } 60


Using. Base. Program類別圖 62

Using. Base. Program片段 (1/3) // Define the base class Car { public virtual void Describe. Car() { System. Console. Write. Line( "Four wheels and an engine. "); } } 63

Using. Base. Program片段 (2/3) // Define the derived classes class Convertible. Car : Car { public new virtual void Describe. Car() { base. Describe. Car(); Console. Write. Line( "A roof that opens up. "); } } 64

Using. Base. Program片段 (3/3) class Minivan : Car { public override void Describe. Car() { base. Describe. Car(); Console. Write. Line( "Carries seven people. "); } } 65

Using. Base. Program. Main()片段 (1/2) // new and override make no differences here Car car 1 = new Car(); car 1. Describe. Car(); Console. Write. Line("-----"); Convertible. Car car 2 = new Convertible. Car(); car 2. Describe. Car(); Console. Write. Line("-----"); Minivan car 3 = new Minivan(); car 3. Describe. Car(); Console. Write. Line("-----"); 66
![Using. Base. Program. Main()片段 (2/2) // they are different in polymorphysm Car[] cars = Using. Base. Program. Main()片段 (2/2) // they are different in polymorphysm Car[] cars =](http://slidetodoc.com/presentation_image_h/146e6ebd046fd6f9a2cdebe4a59c2235/image-67.jpg)
Using. Base. Program. Main()片段 (2/2) // they are different in polymorphysm Car[] cars = new Car[3]; cars[0] = new Car(); cars[1] = new Convertible. Car(); cars[2] = new Minivan(); foreach (Car vehicle in cars) { Console. Write. Line("Car object: " + vehicle. Get. Type()); vehicle. Describe. Car(); Console. Write. Line("-----"); } 67




預設類別System. Object • 一致化型別 • 成員函式 – Equals – Get. Hash. Code – Get. Type – Reference. Equals – To. String – Finalize 71

Inheriting. Object. Program. Main()片段 Test t 1 = new Test(); Test t 2 = new Test(); bool is. Equal = t 1. Equals(t 2); Console. Write. Line(t 1. To. String()); Console. Write. Line("t 1 與t 2 相等為" + is. Equal); 72

Inheriting. Object. Program 片段 class Test { override public string To. String() { return "覆寫Inheriting. Object. Test"; } } 73

Boxing 與 Unboxing int x = 10; Object obj = (Object) x; // boxing obj = 20; int j = (int)obj; // unboxing 74


Liskov 代替性原理 (LSP: Liskov Substitution Principle) • Subtype must be substitutable for their base types • 良好的繼承設計 – 對形態S之每一物件o 1,有形態T的物件o 2,使 在所有利用型態T物件的程式P中,P的行為不 因以o 1代替o 2而改變 • 破壞LSP常也破壞OCP *Robert C. Martin, Agile Software Development: Principles, Patterns, and Practices, Pearson Education, 2003 76


LSPViolation. Example. Program 片段 (1/4) class Rectangle { private int width; private int height; virtual public int Width { set { width = value; } } virtual public int Height { set { height = value; } } 78

LSPViolation. Example. Program 片段 (2/4) public int Area() { return width * height; } } 79

LSPViolation. Example. Program 片段 (3/4) class Square : Rectangle { override public int Width { set { base. Width = value; base. Height = value; } } override public int Height { set { base. Width = value; base. Height = value; } } } 80
![LSPViolation. Example. Program 片段 (4/4) class Program { static void Main(string[] args) { Square LSPViolation. Example. Program 片段 (4/4) class Program { static void Main(string[] args) { Square](http://slidetodoc.com/presentation_image_h/146e6ebd046fd6f9a2cdebe4a59c2235/image-81.jpg)
LSPViolation. Example. Program 片段 (4/4) class Program { static void Main(string[] args) { Square s = new Square(); Test(s); } static void Test(Rectangle r) { r. Width = 5; r. Height = 4; Debug. Assert(r. Area() == 20); } } 81




Abstract. Class. Example. Program. Main() 片段 double a = 5. 0; Square sq = new Square(a); Console. Write. Line("正方形sq之面積為" + sq. Area()); Circle c = new Circle(a); Console. Write. Line("圓形c之面積為" + c. Area()); 85

Abstract. Class. Example. Program 片段 (1/3) public abstract class Shape { private string shape; public Shape(string shape) { this. shape = shape; Console. Write. Line("建立" + shape); } abstract public double Area(); } 86

Abstract. Class. Example. Program 片段 (2/3) public class Square : Shape { double a; public Square(double a): base("正方形") { this. a = a; } public override double Area() { return a * a; } } 87

Abstract. Class. Example. Program 片段 (3/3) public class Circle : Shape { double r; public Circle(double r): base("圓形") { this. r = r; } public override double Area() { return Math. PI * r; } } 88




依存性反轉原理 (DIP: Dependency-Inversion Principle) • High-level modules should not depend on lowlevel modules. Both should depend on abstractions. • Abstractions should not depend on details. Details should depend on abstractions. *Robert C. Martin, Agile Software Development: Principles, Patterns, and Practices, Pearson Education, 2003 92


狀態圖(State Chart) 94

DIPViolation. Example. Program 片段 (1/4) public enum Lamp. Status { OFF = 0, ON = 1 } public enum Button. Status { RELEASED = 0, PRESSED = 1 } 95

DIPViolation. Example. Program 片段 (2/4) public class Lamp { private Lamp. Status status = Lamp. Status. OFF; public Lamp. Status { get { return status; } } public void Turn. On() { status = Lamp. Status. ON; } public void Turn. Off() { status = Lamp. Status. OFF; } } 96

DIPViolation. Example. Program 片段 (3/4) public class Button { private Button. Status status = Button. Status. RELEASED; private Lamp lamp; public Button(Lamp lamp) { this. lamp = lamp; } public Button. Status { get { return status; } } 97

DIPViolation. Example. Program 片段 (4/4) public void Press() { if (status == Button. Status. RELEASED) { status = Button. Status. PRESSED; lamp. Turn. On(); } } public void Release() { if( status == Button. Status. PRESSED ){ status = Button. Status. RELEASED; lamp. Turn. Off(); } } } 98

DIPViolation. Example. Program. Main() 片段 (1/3) Lamp lamp 1 = new Lamp(1); Button button = new Button(lamp 1); Random rand = new Random(); for (int n = 0; n <= 100; ++n) { Console. Write("time n = " + n + "t"); 99

DIPViolation. Example. Program. Main() 片段 (2/3) if (rand. Next() % 2 == 1) { if (button. Status == Button. Status. PRESSED) { button. Release(); } else { button. Press(); } } 100

DIPViolation. Example. Program. Main() 片段 (3/3) if (lamp 1. Status == Lamp. Status. OFF) { Console. Write. Line("lamp 1 is off"); } else { Console. Write. Line("lamp 1 is on"); } Console. Write. Line(); } 101



Using. Interface. Program. Main() 片段 double a = 5. 0; Square sq = new Square(a); Console. Write. Line("正方形sq之面積為" + sq. Area()); Circle c = new Circle(a); Console. Write. Line("圓形c之面積為" + c. Area()); 104

Using. Interface. Program片段(1/3) interface Shape { double Area(); } 105

Using. Interface. Program片段(2/3) public class Square : Shape { double a; public Square(double a) { this. a = a; } public double Area() { return a * a; } } 106

Using. Interface. Program片段(3/3) public class Circle : Shape { double r; public Circle(double r) { this. r = r; } public double Area() { return Math. PI * r; } } 107

介面 vs. 抽象類別 (1/2) interface Shape { double Area(); } ----------------------public abstract class Shape { private string shape; public Shape(string shape) { this. shape = shape; Console. Write. Line("建立" + shape); } abstract public double Area(); } 108

介面 vs. 抽象類別 (2/2) public class Square : Shape {. . . public double Area() { return a * a; } } ----------------------public class Square : Shape {. . . public override double Area() { return a * a; } } 109


Button. And. Lamp. Program (1/4) public interface Switchable. Device { void Turn. On(); void Turn. Off(); } public enum Lamp. Status { OFF = 0, ON = 1 } public enum Button. Status { RELEASED = 0, PRESSED = 1 } 111

Button. And. Lamp. Program (2/4) public class Lamp : Switchable. Device { private Lamp. Status status = Lamp. Status. OFF; public Lamp. Status { get { return status; } } public void Turn. On() { status = Lamp. Status. ON; } public void Turn. Off() { status = Lamp. Status. OFF; } } 112

Button. And. Lamp. Program (3/4) public class Button { private Button. Status status = Button. Status. RELEASED; private Switchable. Device device; public Button(Switchable. Device device) { this. device = device; } public Button. Status { get { return status; } } 113

Button. And. Lamp. Program (4/4) public void Press() { if (status == Button. Status. RELEASED) { status = Button. Status. PRESSED; device. Turn. On(); } } public void Release() { if (status == Button. Status. PRESSED) { status = Button. Status. RELEASED; device. Turn. Off(); } } } 114



介面分離原理 (ISP: Interface-Segregation Principle) • Clients should not be forced to depend on methods that they do not use • 避免同一介面中有目的不同的多群函式宣 告 117


ISPViolation. Example. Program 片段 (1/4) interface Timer. Client { void Time. Out(); } interface Door : Timer. Client { void Lock(); void Unlock(); bool Is. Open(); } enum Door. Status { CLOSED = 0, OPEN = 1 } 119

ISPViolation. Example. Program 片段 (2/4) class Timer { private int t; private int timeout; private Timer. Client client; public Timer(int timeout, Timer. Client client) { this. timeout = timeout; this. client = client; t = 0; } 120

ISPViolation. Example. Program 片段 (3/4) public void Advance() { ++t; if (t % timeout == 0) { client. Time. Out(); } } } class Timed. Door : Door { private Door. Status status = Door. Status. CLOSED; 121

ISPViolation. Example. Program 片段 (4/4) public bool Is. Open() { return (status == Door. Status. OPEN); } public void Lock() { if (Is. Open()) status = Door. Status. CLOSED; } public void Unlock() { if (!Is. Open()) status = Door. Status. OPEN; } public void Time. Out() { Lock(); } } 122

ISPViolation. Example. Program. Main() 片段(1/2) Timed. Door t. Door = new Timed. Door(); int timeout = 10; Timer timer = new Timer(timeout, t. Door); int n; const int N = 20; t. Door. Unlock(); for (n = 0; n <= N; ++n) { 123

ISPViolation. Example. Program. Main() 片段(2/2) if (t. Door. Is. Open()) { Console. Write. Line( "n = " + n + "t t. Door is open"); } else { Console. Write. Line( "n = " + n + "t t. Door is closed"); } timer. Advance(); } 124


程式Multi. Interface類別圖 126

Multi. Interface. Program. Main()片段 Floatplane fp = new Floatplane(); fp. Sail(); fp. Fly(); 127

Multi. Interface. Program片段 (1/2) interface Plane { void Fly(); } interface Ship { void Sail(); } 128

Multi. Interface. Program片段 (2/2) public class Floatplane : Plane, Ship { public Floatplane() { Console. Write. Line("建立水上飛機"); } public void Sail() { Console. Write. Line("水上滑行"); } public void Fly() { Console. Write. Line("空中飛行"); } } 129



Timed. Door. Simulation. Program 片段 interface Timer. Client { void Time. Out(); } interface Door { void Lock(); void Unlock(); bool Is. Open(); }. . . class Timed. Door : Door, Timer. Client {. . . } 132


程式Cast. Multi. Interfaces類別圖 134

Cast. Multi. Interfaces. Program. Main()片段 double a = 5. 0; Square sq = new Square(a); Rhombus rhomb = sq as Rhombus; Console. Write. Line( "sq的面積以菱形公式計算得"+rhomb. Area() ); if( sq is Rectangle ) { Rectangle rec = (Rectangle) sq; Console. Write. Line( "sq的面積以矩形公式計算得"+rec. Area() ); } 135

Cast. Multi. Interfaces. Program 片段(1/3) interface Rectangle { double Area(); } interface Rhombus { double Area(); } 136

Cast. Multi. Interfaces. Program 片段(2/3) public class Square : Rectangle, Rhombus { private double a; private double d; public Square(double a) { this. a = a; d = Math. Sqrt(2. 0) * a; } 137

Cast. Multi. Interfaces. Program 片段(3/3) double Rectangle. Area() { return a * a; } double Rhombus. Area() { return 0. 5 * d; } } 138
- Slides: 138