c#中的多态 c#中的委托
C#中的多态性
- 方法名必须相同
 - 参数列表必须不相同
 - 返回值类型可以不相同
 


        public void Sleep()
        {
            Console.WriteLine("Animal睡觉");
        }
        public int Sleep(int time)
        {
            Console.WriteLine("Animal{0}点睡觉", time);
            return time;
        }


2、重写(override):子类中为满足自己的需要来重复定义某个方法的不同实现,需要用override关键字,被重写的方法必须是虚方法,用的是virtual关键字。它的特点是(三个相同):
- 相同的方法名
 - 相同的参数列表
 - 相同的返回值。
 
        public virtual void EatFood()
        {
            Console.WriteLine("Animal吃东西");
        } 
子类中的定义:
        public override void EatFood()
        {
            Console.WriteLine("Cat吃东西");
            //base.EatFood();
        }
| tips:经常有童鞋问重载和重写的区别,而且网络上把这两个的区别作为C#做常考的面试题之一。实际上这两个概念完全没有关系,仅仅都带有一个“重”字。他们没有在一起比较的意义,仅仅分辨它们不同的定义就好了。 | 
        public virtual void EatFood()
        {
            Console.WriteLine("Animal吃东西");
        }
            Animal a = new Animal();
            a.EatFood();



    public abstract class Biology
    {
        public abstract void Live();
    }
    public class Animal : Biology
    {
        public override void Live()
        {
            Console.WriteLine("Animal重写的抽象方法");
            //throw new NotImplementedException();
        }
    }



| 虚方法和抽象方法的区别是:因为抽象类无法实例化,所以抽象方法没有办法被调用,也就是说抽象方法永远不可能被实现。 | 
        public void Sleep()
        {
            Console.WriteLine("Animal Sleep");
        }
则在派生类Cat中定义隐藏方法的代码为:
        new public void Sleep()
        {
            Console.WriteLine("Cat Sleep");
        }
            或者为:        public new void Sleep()
        {
            Console.WriteLine("Cat Sleep");
        }    
注意:(1)隐藏方法不但可以隐藏基类中的虚方法,而且也可以隐藏基类中的非虚方法。


    public abstract class Biology
    {
        public abstract void Live();
    }
    public class Animal : Biology
    {
        public override void Live()
        {
            Console.WriteLine("Animal重写的Live");
            //throw new NotImplementedException();
        }
        public void Sleep()
        {
            Console.WriteLine("Animal Sleep");
        }
        public int Sleep(int time)
        {
            Console.WriteLine("Animal在{0}点Sleep", time);
            return time;
        }
        public virtual void EatFood()
        {
            Console.WriteLine("Animal EatFood");
        }
    }
    public class Cat : Animal
    {
        public override void EatFood()
        {
            Console.WriteLine("Cat EatFood");
            //base.EatFood();
        }
        new public void Sleep()
        {
            Console.WriteLine("Cat Sleep");
        }
        //public new void Sleep()
        //{
        //    Console.WriteLine("Cat Sleep");
        //}
    }
    public class Dog : Animal
    {
        public override void EatFood()
        {
            Console.WriteLine("Dog EatFood");
            //base.EatFood();
        }
    }




    class Program
    {
        static void Main(string[] args)
        {
            //Animal的实例
            Animal a = new Animal();
            //Animal的实例,引用派生类Cat对象
            Animal ac = new Cat();
            //Animal的实例,引用派生类Dog对象
            Animal ad = new Dog();
            //Cat的实例
            Cat c = new Cat();
            //Dog的实例
            Dog d = new Dog();
            //重载
            a.Sleep();
            a.Sleep(23);
            //重写和虚方法
            a.EatFood();
            ac.EatFood();
            ad.EatFood();
            //抽象方法
            a.Live();
            //隐藏方法
            a.Sleep();
            ac.Sleep();
            c.Sleep();
            Console.ReadKey();
        }
    }


            //重载
            a.Sleep();
            a.Sleep(23);

            //重写和虚方法
            a.EatFood();
            ac.EatFood();
            ad.EatFood();
在这一段中,a、ac以及ad都是Animal的实例,但是他们引用的对象不同,a引用的是Animal对象,ac引用的是Cat对象,ad引用的是Dog对象,这个差别会造成执行结果的什么差别呢,请看执行结果:

            //抽象方法
            a.Live();

            //隐藏方法
            a.Sleep();
            ac.Sleep();
            c.Sleep();




            //Animal的实例
            Animal a = new Animal();
            //Animal的实例,引用派生类Cat对象
            Animal ac = new Cat();
            //Animal的实例,引用派生类Dog对象
            Animal ad = new Dog();
            a.Sleep();
            a.EatFood();
            ac.EatFood();
            ad.EatFood();



c#中的委托
个人认为,可以从以下2点来理解:
(1) 从数据结构来讲,委托是和类一样是一种用户自定义类型。
(2) 从设计模式来讲,委托(类)提供了方法(对象)的抽象。
委托是方法的抽象,它存储的就是一系列具有相同签名和返回回类型的方法的地址。调用委托的时候,委托包含的所有方法将被执行。 public delegate int MyDelegate (string s);
上面的委托可被用于引用任何一个带有一个单一的 string 参数的方法,并返回一个 int 类型变量
2. 委托定义
delegate void MyDel(int x);
委托类型声明:
(1) 以deleagate关键字开头。
(2)返回类型+委托类型名+参数列表。
3. 声明委托变量
MyDel del1,del2;
4. 初始化委托变量
(1) 使用new运算符
new运算符的操作数的组成如下:
- 委托类型名
 - 一组圆括号,其中包含作为调用列表中的第一个成员的方法的名字。方法可以是实例方法或静态方法。
 
del1 = new MyDel( myInstObj.MyM1 ); del2 = new MyDel( SClass.OtherM2 );
(2)使用快捷语法
快键语法,它仅由方法说明符构成。之所以能这样,是因为在方法名称和其相应的委托类型之间有隐式转换。
del1 = myInstObj.MyM1; del2 = SClass.OtherM2;
5. 赋值委托
由于委托是引用类型,我们可以通过给它赋值来改变包含在委托变量中的方法地址引用。旧的引用会被垃圾回收器回收。
MyDel del; del = myInstaObj.MyM1; //委托初始化 del = SClass.OtherM2;//委托重新赋值,旧的引用将被回收
6. 组合委托
委托可以使用额外的运算符来组合。这个运算最终会创建一个新的委托,其调用列表是两个操作数的委托调用列表的副本的连接。
委托是恒定的,操作数委托创建后不会被改变。委托组合拷贝的是操作数的副本。
MyDel del1 = myObj.MyMethod; MyDel del2 = SClass.OtherM2; MyDel del3 = del1 + del2; //组合调用列表
7. 委托加减运算
可以使用+=运算符,为委托新增方法。
同样可以使用-=运算符,为委托移除方法。
MyDel del = myObj.MyMethod; del += SClass.OtherM2; // 增加方法 del -= myObj.MyMethod; // 移除方法
8. 委托调用
委托调用跟方法调用类似。委托调用后,调用列表的每个方法将会被执行。
在调用委托前,应判断委托是否为空。调用空委托会抛出异常。
if(null != del)
{
     del();//委托调用
}
c#中的多态 c#中的委托的更多相关文章
- 13、java中的多态
		
1,多态的体现 父类的引用指向了自己的子类对象. 父类的引用也可以接收自己的子类对象.2,多态的前提 必须是类与类之间有关系.要么继承,要么实现. 通常还有一个前提:存在覆盖. 3,多态的好处 多态的 ...
 - java中实现多态的机制是什么?
		
多态性是面向对象程序设计代码重用的一个重要机制,我们曾不只一次的提到Java多态性.在Java运行时多态性:继承和接口的实现一文中,我们曾详细介绍了Java实现运行时多态性的动态方法调度:今天我们再次 ...
 - C#中区别多态、重载、重写的概念和语法结构
		
C#中区别多态.重载.重写的概念和语法结构 重写是指重写基类的方法,在基类中的方法必须有修饰符virtual,而在子类的方法中必须指明override. 格式: 基类中: public virtual ...
 - 转载:C#中的多态
		
原文地址 http://www.cnblogs.com/jhxk/articles/1644018.html 感谢博主分享! 之前看到过类似的问题:如果面试时主考官要求你用一句话来描述多态,尽可能的 ...
 - c++中虚多态的实现机制
		
c++中虚多态的实现机制 參考博客:http://blog.csdn.net/neiloid/article/details/6934135 序言 证明vptr指针存在 无继承 单继承无覆盖 单继承有 ...
 - 转:C#中的多态
		
封装.继承.多态,面向对象的三大特性,前两项理解相对容易,但要理解多态,特别是深入的了解,对于初学者而言可能就会有一定困难了.我一直认为学习OO的最好方法就是结合实践,封装.继承在实际工作中的应用随处 ...
 - python中的多态
		
# -*- coding: cp936 -*- #python 27 #xiaodeng #python中的多态 #多态:一个操作的意义取决于被操作对象的类型,相同的消息给予不同的对象会引发不同的动作 ...
 - 第二十二篇:C++中的多态机制
		
前言 封装性,继承性,多态性是面向对象语言的三大特性.其中封装,继承好理解,而多态的概念让许多初学者感到困惑.本文将讲述C++中多态的概念以及多态的实现机制. 什么是多态? 多态就是多种形态,就是许多 ...
 - 简述C++中的多态机制
		
前言 封装性,继承性,多态性是面向对象语言的三大特性.其中封装,继承好理解,而多态的概念让许多初学者感到困惑.本文将讲述C++中多态的概念以及多态的实现机制. 什么是多态? 多态就是多种形态,就是许多 ...
 
随机推荐
- loj2003 「SDOI2017」新生舞会
			
分数规划+KM 算法 这个KM不好,看算法竞赛进阶指南的 #include <iostream> #include <cstring> #include <cstdio& ...
 - SQL server 事务实例
			
简单的SQLserver事务实例: 执行SQL 组合操作A.操作B,只有AB都执行成功时才提交事务,否则回滚事务. 测试数据表: --1.数据表A CREATE TABLE A( A1 VARCHAR ...
 - c++ - 在终端中,cout不显示任何内容
			
g++ 是一个编译器,它将源代码转换成可以执行程序,但不运行它. 你必须亲自运行程序. g++ 生成的程序的默认名称是 a.out ( 因为历史原因),因此你将运行它作为 $./a.out 如果要 ...
 - windows和ubuntu14.04双系统设置默认启动项
			
首先开机或者重启,在启动项选择菜单处记住win7对应的序号,从上至下的序号从0开始计数,我的win7系统选项处于第5个,那么序号就应该是4,记住后,打开ubuntu系统. 2 按下Ctrl+alt+T ...
 - World Finals 2017
			
Need for Speed Sheila is a student and she drives a typical student car: it is old, slow, rusty, a ...
 - 【bzoj3231】[Sdoi2008]递归数列  矩阵乘法+快速幂
			
题目描述 一个由自然数组成的数列按下式定义: 对于i <= k:ai = bi 对于i > k: ai = c1ai-1 + c2ai-2 + ... + ckai-k 其中bj和 cj ...
 - 【Luogu】P3380树套树模板(线段树套Splay)
			
题目链接 幸甚至哉,歌以咏志. 拿下了曾经是那么遥不可及的线段树,学会了曾经高不可攀的平衡树,弄懂了装B的时候才挂在嘴边的树套树. 每道模板都是链上的一颗珠子.把它们挨个串起来,就成为我成长的历程. ...
 - [luoguP2331] [SCOI2005]最大子矩阵(DP)
			
传送门 orz不会做... 一个好理解的做法(n^3*k): 分n=1和n=2两种情况考虑. n=1时,预处理出前缀和sum[]. 设f[i][j]为到达第i格,已经放了j个子矩阵的最大和, 那么每次 ...
 - 洛谷P4094 - [TJOI2016]字符串
			
Portal Description 给出一个字符串\(s(|s|\leq10^5)\)和\(m\)次询问,每次询问子串\(s[x_1..x_2]\)的所有子串和\(s[y_1..y_2]\)的最长公 ...
 - html-Span 指定宽度
			
html-Span 指定宽度 css: span{ display:-moz-inline-box; display:inline-block; width:150px; } 链接:如何设置HTML ...