面向对象(十五)-委托delegate

1. 简介

如果我们要把一个方法当作另一个方法的参数来传递,那么我们就需要用到委托。
简单来讲,委托是一种类型,可以赋值一个方法。
可将任何可访问类或结构中与委托类型匹配的任何方法分配给委托。 该方法可以是静态方法,也可以是实例方法。 这样便能通过编程方式来更改方法调用,还可以向现有类中插入新代码。

2. 语法

写在命名空间中或类中。

   //定义一个委托,可赋值 返回值为空并且参数列表也为空的方法。
    public delegate void PerformFunction1();
    //定义一个委托, 可赋值 返回值为int,不需要参数的方法。
    public delegate int PerformFunction2();

    //定义一个委托, 可赋值 返回值为空,参数列表第一个为int,第二个为string,第三个为float的方法
    public delegate void PerformFunction3(int age, string name, float height);
  
     //定义一个委托, 可指向 返回值为bool, 参数列表为 任意两个同类型的形参
    public delegate bool Compare<in T>(T obj1, T obj2);

    
        static void Main(string[] args)
        {
            // 两种初始化方法
            PerformFunction1 perform1 = new PerformFunction1(testFunction);
            PerformFunction3 perform2 = printPersonDesc;
            
            // 两种调用方法
            perform1();
            perform2.Invoke(18, "张三", 1.87f);
        }

        static void printPersonDesc(int age, string name, float height)
        {
            Console.WriteLine(age + name + height);
        }

        static void testFunction()
        {
            Console.WriteLine("调用了testFunction");
        }

将方法作为参数进行引用的能力使委托成为定义回调方法的理想选择。 例如,对比较两个对象的方法的引用可以作为参数传递到排序算法中。

3.案例

思考如下题目:
张三和李四,李四有几只宠物,现在由于李四要出差,所以麻烦张三在吃完饭后,如果有剩下的饭菜,喂养一下李四的宠物。
李三可以通过工作来获取食物,每次工作都会耗费一些体力,当体力为0时,就无法工作了。 每吃一次饭恢复一点体力


class Person
    {
        private List<string> foodGoods = new List<string>();

        public string name { get; set; }
        public int age { get; set; }
        public List<string> foods = new List<string>();
        public int hungryProgress = 10;
        public Random ran = new Random();

        public Person()
        {

            foodGoods.Add("鸡腿");
            foodGoods.Add("鸭肉");
            foodGoods.Add("牛肉");
            foodGoods.Add("满汉全席");
            foodGoods.Add("火腿肠");
            foodGoods.Add("泡面");
            foodGoods.Add("榨菜");
            foodGoods.Add("炒粉");
            foodGoods.Add("肠粉");
            foodGoods.Add("河粉");
            foodGoods.Add("武大炊饼");
            foodGoods.Add("烧烤");
            foodGoods.Add("鸡蛋盖饭");
            foodGoods.Add("刀削面");
            foodGoods.Add("汉堡");
            foodGoods.Add("意大利面");
            foodGoods.Add("牛排");
        }


        //吃饭并且喂食
        public void eatAndFed(PerformFedFunction fed)
        {
            eat();
            if (this.foods.Count > 0)
            {
                fed(this.foods[0]);
            }
            else
            {
                Console.WriteLine("一不小心都吃完了");
            }
        }

        public void work()
        {
            if (hungryProgress <= 0)
            {
                Console.WriteLine("没力气干活了");
            }
            else
            {
                hungryProgress--;
                int index = ran.Next(0, foodGoods.Count);
                foods.Add(foodGoods[index]);
            }
        }

        private void eat()
        {
            int i = ran.Next(0, foods.Count);
            int j = 0;
            while(j < i)
            { 
                Console.WriteLine("吃饭中....");
                j++;
                foods.RemoveAt(0);
                hungryProgress++;
            }
            Console.WriteLine("吃完饭了.");
        }

    }

Dog类

class Dog
    {
        public string name { get; set; }
        public void eat(string lastFoodName)
        {
            Console.WriteLine("名字为:"+ name +"的狗,正在吃:" + lastFoodName);
        }
    }

Cat类

class Cat
    {
        public string name { get; set; }
        public void eat(string lastFoodName)
        {
            Console.WriteLine("名字为:" + name + "的猫,正在吃:" + lastFoodName);
        }
    }

Program类

public delegate void PerformFedFunction(string foodName);
class Program
    {
        static void Main(string[] args)
        {

            Dog d1 = new Dog();
            d1.name = "李四的小狗";
            Cat c1 = new Cat();
            c1.name = "李四的猫咪";


            PerformFedFunction fedFun1 = d1.eat;
            PerformFedFunction fedFun2 = c1.eat;

            Person p1 = new Person();
            p1.age = 20;
            p1.name = "张三";

            p1.work();
            p1.work();
            p1.work();
            p1.work();
            p1.work();

            p1.eatAndFed(fedFun1);
            p1.eatAndFed(fedFun2);
      }
}

作者:silence_k
链接:http://www.jianshu.com/p/d29d71a9affa
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 1. Java基础部分 基础部分的顺序:基本语法,类相关的语法,内部类的语法,继承相关的语法,异常的语法,线程的语...
    子非鱼_t_阅读 33,730评论 18 399
  • 307、setValue:forKey和setObject:forKey的区别是什么? 答:1, setObjec...
    AlanGe阅读 5,552评论 0 1
  • *面试心声:其实这些题本人都没怎么背,但是在上海 两周半 面了大约10家 收到差不多3个offer,总结起来就是把...
    Dove_iOS阅读 27,475评论 30 472
  • 1. 简介 如果我们要把一个方法当作另一个方法的参数来传递,那么我们就需要用到委托。简单来讲,委托是一种类型,可以...
    silence_k阅读 3,398评论 3 2
  • 如果你只是爱慕我的容颜,那我只能告诉你,我也有变丑的时候;如果你只是爱慕我的身体,那我只能告诉你,我也有干瘪的时候...
    丹娜服饰色彩手绘阅读 3,853评论 0 0

友情链接更多精彩内容