.NET面向对象特性之多态
前言
上一篇总结了面向对象三大特性之一的继承,再接再厉,这一章继续总结多态。同时把继承中涉及到多态的内容进一步补充扩展。可以说“继承”是多态的根基。但继承主要关注的是“共通性”,而多态主要关注的是“差异性”。
一.多态介绍
关于多态的定义:可以呈现不同形式的能力或状态。这一术语来源于生物系统,意指同族生物具有的相同特征。而在.NET 中,多态指同一操作作用于不同的实例,产生不同运行结果的机制。也就是不同对象接受到相同消息时会产生不同动作。
eg:在现实生活中不同的环境下我们表现为不同的角色,遵循不同的规则。比如,在学校我们是我们是学生,在家我们是儿女,在饭店我们是客人,同一个不同环境下不同的角色,不同的规则。
二.编译时多态
编译时多态:是指参数列表的不同, 来区分不同的函数, 在编译后, 就自动变成两个不同的函数名.
1.方法重载:方法名相同而方法参数列表不同。
参数列表不同:(满足以下之一即可)
(1)参数的个数不同
eg: void function(int x,int y) && void function(int x,int y,int z)
(2)参数的个数相同但类型不同
eg:void function (int x,int y) && (void function(string a,string b) || void function(int x,string a) ……)
(3)参数类型和个数相同,但顺序不同
eg:void function(int x,string a) && void function(string a,intx )
注意:方法的返回类型不是方法重载的判断条件。
eg: string function();&&void function() 不构成重载。
当方法重载的个数太多的时候,太多重载就麻烦了,这时可以用参数数组(params数组)。关于参数数组的介绍此处省略。
2.继承中的方法重载
当父类与子类重名时的方法重载:

Class Parent { public void function()
{
Console.WriteLine("parent");
} } Class Child:Parent {
public void function()
{
Console.WriteLine("Child");
}
}

Parent p = new Parent();
p.function(); //输出 parent
Child c=new Child();
c.function(); //输出Child
当父类与子类方法相同时,调用哪个方法由对象变量的类型决定。
Parent p2 = new Child();
p2.function(); //输出parent
所以更准确的说法是:当分别位于父类和子类的方法相同时,调用哪个方法由对象变量的编译时类型决定。
如果需要调用子类的怎么办,这时候就需要强制转换。
((Child)p2).function(); (其实干嘛p2不直接定义为Child类型呢?不是更简单)
好了,运行吧,但是出现了一条警告:隐藏了继承的成员。这时候就需要用到new关键字来消除隐藏。
方法重载是在编译的时候根据参数列表的不同,从而调动了方法名相同的不同函数。这就体现了多态的特点,对同一消息产生不同动作。它是在编译时确定的,所以是编译时多态。
……先讲到这里,请对比下面运行时多态中的虚函数的多态……
2.运算符重载
为了解决同一操作符施加于不同类型的对象时拥有不同的含义的问题,提供了运算符重载。
eg:我们可以对数字进行相加,但是有时候我们需要对不同对象里的数字进行相加,比如,我们数学上的两个复数相x1=a+bi,x2=c+di,对x1和x2相加。
格式为:
public static 返回值类型 operator unary-operator ( 参数列表 ) {
方法体
}
这里给出一个一元运算符重载的例子:
class Point
{
private int x,y;
public Point(int a, int b)
{
x = a;
y = b;
}
public static Point operator ++(Point p)
{
p.x ++;
p.y ++;
return p;
}
public void Display()
{
Console.WriteLine("Point.x = {0}, Point.y = {1}",x,y);
}
public static Point operator +(Point p1,Point p2)
{
Point p = new Point(0,0);
p.x = p1.x + p2.x;
p.y = p1.y + p2.y;
return p;
}
static void Main(string[] args)
{
Point a = new Point(10,20);
Point b = new Point(30,40);
a = a + b;
a.Display();
a ++;
a.Display();
}
}
运算符重载例子
注意:是几元运算符,参数就有几个。
总结:编译时的多态,一般包括方法重载和运算符重载,在编译时通过方法的参数列表和返回值决定不同操作。(这里指的是非虚函数的情况下)
三.运行时多态
运行时多态:也就是动态绑定,是指在执行期间(而非编译期间)判断所引用对象的实际类型,根据实际类型判断并调用相应的属性和方法。(在程序运行前不知道,会调用那个方法, 而到运行时, 通过运算程序,动态的算出被调用的地址. 动态调用在继承的时候,方法名 参数列表完全相同时才出现运行时多态!)
1.虚函数
先看代码
public abstract class Animal
{
public abstract void ShowType();
public void Eat()
{
Console.WriteLine("Animal always eat.");
}
}
public class Bird: Animal
{
private string type = "Bird";
public override void ShowType()
{
Console.WriteLine("Type is {0}", type);
}
private string color;
public string Color
{
get { return color; }
set { color = value; }
}
}
public class Chicken : Bird
{
private string type = "Chicken";
public override void ShowType()
{
Console.WriteLine("Type is {0}", type);
}
public void ShowColor()
{
Console.WriteLine("Color is {0}", Color);
}
//测试
public class Test
{
public static void Main()
{
Bird bird = new Bird();
Chicken chicken = new Chicken();
}
}
虚函数
由于 Animal 为抽象类,我们只创建 Bird 对象和 Chicken对象。
很容易看就知道bird的引用类型是Bird,而创建的对象也是Bird。Chicken的引用类型是Chicken,创建的对象是Chicken。
再看这行代码:Bird bird2 = new Chicken();
bird2是什么类型呢?bird2对象调用子类还是父类的方法?
在这种情况下(虚方法)bird2的调用方法,取决于其创建的对象类型,而不是它的引用类型。如上 Bird bird2 = new Chicken()时,bird2创建对象为 Chicken 类型,而不用关注 bird2 的引用类型是否为 Bird。引用类型只是决定了方法的访问权限。
也可以这样理解:
Bird bird2=new Chicken();可以看做
Bird bird2=new Bird();
Chiken chiken=new Chiken();
bird2=chiken;
所以,bird2还是chiken对象。那么这个引用类型Bird有什么用?被子类隐藏掉的方法,必须通过转化为父类才能调用其方法。否则只能访问子类的方法。通过这种转换就可以调用父类中被隐藏的方法。
调用虚函数时,具体调用哪个函数不是在编译时候确定的,而是在运行时根据对象的真实类型而定的。
2.抽象类
略
3.接口多态
暂时还来不及总结,不过看到一篇不错的博文:http://www.cnblogs.com/if404/archive/2011/10/28/2227197.html
待续……
目前水平有限,随着学习的深入会不断更新,精益求精。欢迎补充。
说明:我是IT边上的一只蜗牛,尽管前面道路漫漫,但我始终渴望前行。
.NET面向对象特性之多态的更多相关文章
- oc面向对象特性: 多态
多态:不同对象以自己的方式响应相同的消息的能力叫做多态. 多态的主要好处就是简化了编程接口.在类与类之间可以重复命名. 下面的例子是一个彩色打印机和黑白打印机这两种打印机,然后Person类中有一 ...
- C#的面向对象特性之多态
using System; using System.Collections; using System.Collections.Generic; namespace codeTest { class ...
- .NET面向对象特性之“继承”
整体简介 1.理解继承——继承关系图 2.实现继承与接口多继承 3.new. virtual.override方法 4.抽象方法和抽象类的继承 5.继承的本质 6.继承的复用性.扩展性和安全性 7.多 ...
- 【游戏开发】在Lua中实现面向对象特性——模拟类、继承、多态
一.简介 Lua是一门非常强大.非常灵活的脚本语言,自它从发明以来,无数的游戏使用了Lua作为开发语言.但是作为一款脚本语言,Lua也有着自己的不足,那就是它本身并没有提供面向对象的特性,而游戏开发是 ...
- 3.java面向对象编程三大特性之多态
面向对象编程的三大特性:封装.继承.多态 封装隐藏了类的内部实现机制,可以在不影响使用的情况下改变类的内部结构,同时也保护了数据.对类的外部而言它的内部实现细节是隐藏的,暴露给外界的只是它的实现方法. ...
- Java基础-面向对象第三大特性之多态(polymorphism)
Java基础-面向对象第三大特性之多态(polymorphism) 作者:尹正杰 版权声明:原创作品,谢绝转载!否则将追究法律责任. 一.多态概述 多态是继封装,继承之后,面向对象的第三大特性,多态的 ...
- Java语言中的面向对象特性:封装、继承、多态,面向对象的基本思想(总结得不错)
Java语言中的面向对象特性(总结得不错) [课前思考] 1. 什么是对象?什么是类?什么是包?什么是接口?什么是内部类? 2. 面向对象编程的特性有哪三个?它们各自又有哪些特性? 3. 你知道jav ...
- Java学习笔记二十五:Java面向对象的三大特性之多态
Java面向对象的三大特性之多态 一:什么是多态: 多态是同一个行为具有多个不同表现形式或形态的能力. 多态就是同一个接口,使用不同的实例而执行不同操作. 多态性是对象多种表现形式的体现. 现实中,比 ...
- 【转载】【游戏开发】在Lua中实现面向对象特性——模拟类、继承、多态
[游戏开发]在Lua中实现面向对象特性——模拟类.继承.多态 阅读目录 一.简介 二.前提知识 三.Lua中实现类.继承.多态 四.总结 回到顶部 一.简介 Lua是一门非常强大.非常灵活的脚本语 ...
随机推荐
- 蓝桥杯 BASIC 27 矩阵乘法(矩阵、二维数组)
[思路]:注意0次幂是单位矩阵. [AC代码]: #include <iostream> #include <algorithm> #include <iomanip&g ...
- POJ 3233 Matrix Power Series(矩阵高速功率+二分法)
职务地址:POJ 3233 题目大意:给定矩阵A,求A + A^2 + A^3 + - + A^k的结果(两个矩阵相加就是相应位置分别相加).输出的数据mod m. k<=10^9. 这 ...
- HDFS副本放置策略和机架感知
副本放置策略 的副本放置策略的基本思想是: 第一block在复制和client哪里node于(假设client它不是群集的范围内,则这第一个node是随机选取的.当然系统会尝试不选择哪些太满或者太忙的 ...
- Meteor入门
转载Meteor入门介绍 Meteor是什么 基于nodejs的实时web APP开发框架. Meteor能带来什么 简单的说,你可以用js搞定客户端.服务端的开发.另外,客户端.服务端的界限被极 ...
- Web前端开发实用的Chrome插件
Web前端开发实用的Chrome插件 越来越多的前端开发人员喜欢在Chrome里开发调试代码,Chrome有许多优秀的插件可以帮助前端开发人员极大的提高工作效率.尤其Chrome本身是可以登录的,登录 ...
- JavaScript中获取当前项目的绝对路径
近期在做JavaWeb项目相关的东西,差点儿每天都遇到非常多问题,主要是由于自己对JavaWeb方面的知识不是非常清楚,尽量把自己在项目中遇到的问题都记录下来,方便以后查阅. 在我们的项目中有这种须要 ...
- 【百度地图API】今日小年大进步,齐头共进贺佳节——API优化升级上线,不再增加内存消耗
原文:[百度地图API]今日小年大进步,齐头共进贺佳节--API优化升级上线,不再增加内存消耗 任务描述: 今天是2011年01月26日,小年夜.百度地图API在小年夜献给广大API爱好者一份给力的礼 ...
- Cocos2d-x 3.0 编译出错 解决 error: expected ';' at end of member declaration
近期把项目移植到cocos2d-x 3.0,在整Android编译环境的时候,出现一大堆的编译出错,都是类似"error: expected ';' at end of member dec ...
- javascript中三目运算符和if else有什么区别
javascript中三目运算符和if else有什么区别今天写了一个图片轮播的小demo,用到了判断先试了一下if else,代码如下:if(n >= count-1){n =0;}else{ ...
- linux下crontab的使用实现
1 crontab实现定时任务 1.1服务状态 /sbin/service crond status 查看定时任务的服务是否启动 参数:start 启动服务 Stop 停止服务 R ...