打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
实现在派生类中引发基类事件

 

 

在创建可用作其他类的基类的类时,应考虑如下事实:事件是特殊类型的委托,只可以从声明它们的类中调用。派生类无法直接调用基类中声明的事件。尽管有时需要事件仅由基类引发,但在大多数情形下,应该允许派生类调用基类事件。(:之所以可以在父类引发,是因为运行时状态下父类只是指向子类的指针,这样即使给事件传递参数this,也是子类而不是父类)为此,您可以在包含该事件的基类中创建一个受保护的调用方法。通过调用或重写此调用方法,派生类便可以间接调用该事件。

关键:1、基类中定义事件、并且定义虚方法触发事件,例子中OnShapeChanged()

      2子类可以通过调用或重写OnShapeChanged间接触发基类事件。

namespace

ConsoleApplication1

{

    class Program

    {

        static void Main(string[] args)

        {

            Circle c1 = new Circle();        

            ShapeContainer sc = new ShapeContainer();

            // Add the shapes to the container.

            sc.AddShape(c1);

            // Cause some events to be raised.

            c1.Update(57);

        }

    }

    public abstract  class Shape

{

       // The event. Note that by using the generic EventHandler<T> event type

        // we do not need to declare a separate delegate type.

        public event EventHandler<ShapeEventArgs> ShapeChanged;

 

        // Make a temporary copy of the event to avoid possibility of
            // a race condition if the last subscriber unsubscribes
            // immediately after the null check and before the event is raised.

        protected virtual void OnShapeChanged(ShapeEventArgs e)

        {

            EventHandler<ShapeEventArgs> handle = ShapeChanged;

            if (handle != null)

            { handle(this, e); }

        }

        public abstract void Draw();       

    }

    public class Circle : Shape

    {

        public override void Draw()

        {

         //   throw new NotImplementedException();

        }

        protected override void OnShapeChanged(ShapeEventArgs e)

        { // Call the base class event invocation method.

            base.OnShapeChanged(e);

        }

        public void Update(double d)       

{           

            OnShapeChanged(new ShapeEventArgs(100));

        }

    }

    public class ShapeContainer

    {

        List<Shape> _list;

        public ShapeContainer()

        {

            _list = new List<Shape>();

        }

        public void AddShape(Shape s)

        {

            _list.Add(s);

            // Subscribe to the base class event.

            s.ShapeChanged += HandleShapeChanged;

        }

        // ...Other methods to draw, resize, etc.

        private void HandleShapeChanged(object sender, ShapeEventArgs e)

        {

            Shape s = (Shape)sender;

            // Diagnostic message for demonstration purposes.

            Console.WriteLine("Received event. Shape area is now {0}", e.NewArea);

            // Redraw the shape here.

            s.Draw();

        }

    }

    public class ShapeEventArgs : EventArgs

    {

        private double newArea;

        public ShapeEventArgs(double d)

        {

            newArea = d;

        }

        public double NewArea

        {

            get { return newArea; }       }    }}

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
Java多态的实现
设计模式之装饰器模式(decorator pattern)
在Java代码中使用抽象类及接口(抽象类与接口的定义,使用与其作用详解)
Java学习笔记(四):理解接口 事件监听器
C++函数的覆盖与再现例子
JAVA类的方法调用和变量
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服