在派生类中引发基类事件
1、? 在創建基類時,若涉及到事件,事件是特殊類型的委托,只可以從聲明它們的類中調用,派生類無法直接調用基類中聲明的事件,但是在多數情況,會需要允許派生類調用基類事件,這時,可以再包含該事件的基類中創建一個受保護的虛調用方法,通過調用或重寫此調用方法,派生類便可以間接調用該事件。
注:不要在基類中聲明虛擬事件,也不要在派生類中重寫這些事件,C#編譯器無法正確處理這些事件,并且無法預知該派生的事件的用戶是否真正訂閱了基類事件。
和下面的程序示例都來自:https://msdn.microsoft.com/zh-cn/library/hy3sefw3.aspx
2、 ?插入知識點:virtual和abstract的區別:
virtual和abstract都是用來修飾父類的,通過覆蓋父類的定義,讓子類重新定義(子類方法前都必須添加override),因此虛擬方法和抽象方法都不能是私有的;
virtual修飾的方法必須有實現(哪怕是僅僅添加一對大括號),而abstract修飾的方法一定不能實現;
?virtual可以被子類重寫,而abstract必須被子類重寫;
如果類成員被abstract修飾,則該類前必須添加abstract,因為只有抽象類才可以有抽象方法;
無法創建abstract類的實例;
3、示例程序
1 namespace Test0301 2 { 3 class Program 4 { 5 static void Main(string[] args) 6 { 7 Circle c1 = new Circle(7); 8 Rectangle r1 = new Rectangle(12, 9); 9 ShapeContainer sc = new ShapeContainer(); 10 11 sc.AddShape(c1); 12 sc.AddShape(r1); 13 14 c1.Update(1); 15 r1.Update(7, 7); 16 17 Console.WriteLine("Press any key to ecit..."); 18 Console.ReadKey(); 19 } 20 } 21 22 public class ShapeEventArgs : EventArgs 23 { 24 private double newArea; 25 26 public ShapeEventArgs(double d) 27 { 28 newArea = d; 29 } 30 31 public double NewArea 32 { 33 get { return newArea; } 34 } 35 } 36 37 public abstract class Shape 38 { 39 protected double area; 40 41 public double Area 42 { 43 get { return area; } 44 set { area = value; } 45 } 46 47 public event EventHandler<ShapeEventArgs> ShapeChanged; 48 49 public abstract void Draw();//abstract和類定義的abstract對應,在派生類中必須實現 50 51 //基類可以重載此函數,實現實際對象類型的此函數 52 //此函數為事件句柄的實現函數 53 protected virtual void OnShapeChanged(ShapeEventArgs e) 54 { 55 Console.WriteLine("基類事件處理函數被{0}調用", this.ToString()); 56 57 EventHandler<ShapeEventArgs> handler = ShapeChanged; 58 if (handler != null) 59 { 60 handler(this, e); //this為調用此函數的派生類對象 61 } 62 } 63 } 64 65 public class Circle : Shape 66 { 67 private double radius; 68 69 public Circle(double d) 70 { 71 radius = d; 72 area = 3.14 * radius * radius; 73 } 74 75 public void Update(double d) 76 { 77 radius = d; 78 area = 3.14 * radius * radius; 79 OnShapeChanged(new ShapeEventArgs(area)); 80 } 81 82 protected override void OnShapeChanged(ShapeEventArgs e) 83 { 84 //具體類的處理 85 Console.WriteLine("Circle's radius changed!"); 86 87 //調用基類的函數 88 base.OnShapeChanged(e); 89 } 90 91 public override void Draw() 92 { 93 Console.WriteLine("Drawing a circle"); 94 Console.WriteLine(); 95 } 96 } 97 98 public class Rectangle : Shape 99 { 100 private double length; 101 private double width; 102 103 public Rectangle(double length,double width) 104 { 105 this.length = length; 106 this.width = width; 107 area = length * width; 108 } 109 110 public void Update(double length, double width) 111 { 112 this.length = length; 113 this.width = width; 114 area = length * width; 115 OnShapeChanged(new ShapeEventArgs(area)); 116 } 117 118 protected override void OnShapeChanged(ShapeEventArgs e) 119 { 120 Console.WriteLine("Rectangle's radius changed!"); 121 base.OnShapeChanged(e); 122 } 123 124 public override void Draw() 125 { 126 Console.WriteLine("Drawing a rectangle!"); 127 Console.WriteLine(); 128 } 129 } 130 131 public class ShapeContainer 132 { 133 List<Shape> _list; 134 135 public ShapeContainer() 136 { 137 _list = new List<Shape>(); 138 } 139 140 public void AddShape(Shape s) 141 { 142 _list.Add(s); 143 //訂閱基類事件 144 s.ShapeChanged += HandleShapeChanged; 145 } 146 147 private void HandleShapeChanged(object sender, ShapeEventArgs e) 148 { 149 Shape s = (Shape)sender; 150 151 Console.WriteLine("Receicved event,Shape area is now {0}", e.NewArea); 152 153 s.Draw(); 154 } 155 } 156 }?
轉載于:https://www.cnblogs.com/xyl-share-happy/p/4307400.html
總結
以上是生活随笔為你收集整理的在派生类中引发基类事件的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 八个JS中你见过的类型。
- 下一篇: 理解Promise (4)