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++中多态的概念以及多态的实现机制. 什么是多态? 多态就是多种形态,就是许多 ...
随机推荐
- UnicodeDecodeError: 'gbk' codec can't decode byte 0xae in position 167: illegal multibyte sequence
UnicodeDecodeError: 'gbk' codec can't decode byte 0xae in position 167: illegal multibyte sequence文件 ...
- 设置vim配置文件使得tab为4个空格
1 set ts=4 2 set expandtab 3 set autoindent
- jQuery获得页面元素的绝对/相对位置
获取页面某一元素的绝对X,Y坐标,可以用offset()方法: var X = $('#DivID').offset().top; var Y = $('#DivID').offset().left; ...
- 【Luogu】P1306斐波那契公约数(递推)
题目链接 有个定理叫gcd(f(n),f(m))=f(gcd(n,m)) 所以递推就好了. #include<cstdio> #include<cstdlib> #includ ...
- 【单调队列优化dp】uestc 594 我要长高
http://acm.uestc.edu.cn/#/problem/show/594 [AC] #include<bits/stdc++.h> using namespace std; t ...
- 学习shell脚本之乘法口诀
脚本如下: #!/bin/bash for i in 'seq 1 9' do for j in 'seq 1 $i' do k=$[$i*$j] echo -ne "$j"&qu ...
- Vmware error:无法获得 VMCI 驱动程序的版本: 句柄无效。
error:无法获得 VMCI 驱动程序的版本: 句柄无效.驱动程序“vmci.sys”的版本不正确.请尝试重新安装 VMware Workstation.开启模块 DevicePowerOn 的操作 ...
- FreeMarker常用语法学习
1.API网址 http://freemarker.sourceforge.net/docs/ 2.一个Table的例子 freemarker 对表格的控制 这里将所有需要在一个区域显示到数据全部ad ...
- uva 11997 优先队列
K Smallest Sums You're given k arrays, each array has k integers. There are kk ways to pick exactly ...
- css样式---隐藏元素
1.通过设置width:0;或height:0 2.将元素的opacity设置成0 3.通过定位将元素移出屏幕范围 4.通过text-indent实现隐藏文字的效果 5.通过z-index隐藏一个元素 ...