C#OOP之七 多态的学习和使用
2016-04-27 21:00
766 查看
多态
什么是多态,看看大辞典的:可以呈现不同形式的能力或状态。这一术语来源于生物系统,意指同族生物具有的相同特征。而在.Net中,多态指同一操作作用于不同的实例,产生不同运行结果的机制。
多态可以分为静态多态和动态,即编译时多态和运行时多态。静态多态比如,汉语中有“打”这个字,但是与不同的字组合,则形成了不同的单词组合,来代表不同的含义,如打饭、打架、打车、打卡等,这种方式是在实现已经定义好了的意思,不管谁打饭、谁打架都代表一样的意思,类似于编译器首先将同名称的代码定义好了,编程中的具体实现是重载;
动态测试,相同的词语而不同对象执行不同的行为,听到“Cut”后,理发师执行的动作是剪断头发,外科医生切开皮肤做手术,演员停止表演。在编程中即运行时多态,不同对象对于同一个方法(Cut)调用的不同行为。
静态多态:即编译器就确定类、方法的关联关系,一般以方法重载来实现。如我们熟悉的计算器为例:
/*功能:实现计算器;将计算功能和用户输入分离
时间:08/09/09 星期二 第二节课
版本:6.1.1
//构成方法重载的前提是;方法名一致,参数个数不同、参数类型不一致、参数顺序不一样
*/
usingSystem; class Calc { private double result; //再增加一个结果变量 public double Jia(double num1,doublenum2) //加法运算:形参:num1,num2 { result=num1+num2+100; return result; } public int Jia(int num1,int num2) { result=num1+num2+200; return (int)result; } publicdouble Jian(double num1,double num2) //减法运算 { result=num1-num2; return result; } public int Jian(int num1,int num2) //减法运算 { result=num1-num2; return (int)result; } public double Cheng(double num1,double num2) //乘法运算 { result=num1*num2; return result; } public double Chu(double num1,doublenum2) //除法运算 { result=num1/num2; return result; } public double PingFang(double num1) { result=num1*num1; return result; } public double NciFang(double num1,doublenum2) //num1:2的num2:5次方 { result=1; //定义result为1 for(int i=1;i<=num2;i++) { result=result*num1; } return result; } } /**********客户端类,即界面类***********/ classClacGUI { static void Main() { Calc jisuanqi; //jisuanqi=? jisuanqi=new Calc(); int x,y; //x,y为Main()的局部变量 Console.Write("请输入第一个数字:"); x=Convert.ToInt32(Console.ReadLine()); Console.Write("请输入第二个数字:"); y=Convert.ToInt32(Console.ReadLine()); char op; //op为Main()的局部变量,表示操作符 Console.Write("请输入您要进行的运算:+ - * / ^:"); //^:表示求N次方 op=Convert.ToChar(Console.ReadLine()); switch(op) { case '+': //加运算 Console.WriteLine(jisuanqi.Jia(x,y)); break; case '-': Console.WriteLine(jisuanqi.Jian(x,y)); break; case '*': //加运算 Console.WriteLine(jisuanqi.Cheng(x,y)); break; case '/': if(y==0) Console.WriteLine("除数不能为0"); else Console.WriteLine(jisuanqi.Chu(x,y)); break; case '^': Console.WriteLine(jisuanqi.NciFang(x,y)); break; default: Console.WriteLine("其他无效选择!!!"); break; } } }
动态多态:也叫动态绑定(后期绑定),是在运行时通过虚方法、重写机制来实现。在.Net中虚方法以virtual关键字来标记。再来复习下virtual和override。
virtual关键字用于修饰方法、属性、索引器或事件声明,并使它们可以在派生类中被重写。例如,此方法可被任何继承它的类重写。
默认情况下,方法是非虚拟的。不能重写非虚方法。
在该示例中,Dimensions类包含x、y两个坐标和Area()虚方法。不同的形状类,如Circle、Cylinder和Sphere继承Dimensions类,并为每个图形计算表面积。每个派生类都有各自的Area()重写实现。根据与此方法关联的对象,通过调用适当的Area()实现,程序为每个图形计算并显示适当的面积。
在前面的示例中,注意继承的类 Circle、Sphere和Cylinder都使用了初始化基类的构造函数,
using System; class TestClass { publicclass Dimensions { public const double PI = Math.PI; protecteddouble x, y; public Dimensions() { } public Dimensions(double x, double y) { this.x = x; this.y = y; } public virtual double Area() { return x * y; } } public class Circle : Dimensions { public Circle(double r) : base(r, 0) { } public override double Area() { return PI * x * x; } } classSphere : Dimensions { public Sphere(double r) : base(r, 0) { } public override double Area() { return 4 * PI * x * x; } } classCylinder : Dimensions { public Cylinder(double r, double h) : base(r, h) { } public override double Area() { return 2 * PI * x * x + 2 * PI * x * y; } } staticvoid Main() { double r = 3.0, h = 5.0; Dimensions c = new Circle(r); Dimensions s = new Sphere(r); Dimensions l = new Cylinder(r, h); // Displayresults: Console.WriteLine("Area of Circle = {0:F2}", c.Area()); Console.WriteLine("Area of Sphere = {0:F2}", s.Area()); Console.WriteLine("Area of Cylinder = {0:F2}", l.Area()); } }
效果如下:
Area ofCircle = 28.27
Area ofSphere = 113.10
Area ofCylinder = 150.80
虚方法和抽象方法的区别如下:
动态多态程序案例如下:
using System; public class DrawingObject { public virtual void Draw() { Console.WriteLine("画形状的基类"); } } public class Line :DrawingObject { public override void Draw() { Console.WriteLine("画一条线"); } } public class Circle : DrawingObject { public override void Draw() { Console.WriteLine("画一个圆"); } } public class Square : DrawingObject { public override void Draw() { Console.WriteLine("画一个正方形"); } } public classDrawDemo { public static int Main(string[] args) { DrawingObject[] dObj = new DrawingObject[4]; dObj[0] = new Line(); dObj[1] = new Circle(); dObj[2] = new Square(); dObj[3] = new DrawingObject(); foreach (DrawingObject drawObj in dObj) { drawObj.Draw(); } return 0; } }
输出结果是:
画一条线
画一个圆
画一个正方形
画形状的基类
/*代码分析:
在DrawDemo类中的Main()方法中,创建了一个数组,数组元素是DrawingObject 类的对象。该数组名为dObj,是由四个DrawingObject类型的对象组成。
接下来, 初始化dObj数组, 由于Line, Circle和Square类都是DrawingObject类的派生类,所以这些类可以作为dObj数组元素的类型。 如果C#没有这种功能,你得为每个类创建一个数组。继承的性质可以让派生对象当作基类成员一样用,这样就节省了编程工作量。
一旦数组初始化之后,接着是执行foreach循环,寻找数组中的每个元素。在每次循环中, dObj 数组的每个元素(对象)调用其Draw()方法。多态性体现在:在运行时,各自调用每个对象的Draw()方法。尽管dObj 数组中的引用对象类型是DrawingObject,这并不影响派生类重载DrawingObject 类的虚方法Draw()。 在dObj 数组中,通过指向DrawingObject 基类的指针来调用派生类中的重载的Draw()方法。
*/
|
A.你可以通过实现接口来实现多态 C.你可以通过继承实现多态
C.你可以通过封装实现多态 D.你可以通过使用抽象类实现多态
2.下面哪个是函数重载的例子?()
A. void example(); B. voidexample1();
char example(); void example2();
C. void example1(int,int); D. voidexample1(int,int);
void example2(char,char); void example1(char,char);
3.下列哪个不属于函数签名:()
A.参数类型 B.参数顺序 C.参数数量 D.参数名称
4.考虑下面的语句:
A.在动态多态中,程序的适当方法可以被调用,依赖于上下文。
B.在前期绑定中,函数在运行时被绑定。
5关于这些语句下面哪个选项是正确的?()
A.语句A为真,语句B为假 B. 语句A为假,语句B为真
C.两个语句A和B都是真 D. 两个语句A和B都是假
|
u 多态是什么
u 多态的分类和使用
u 多态的好处
|
Hour 小时
Maximum 最大值
Minimum 最小值
Argument 参数
Location 定位
Chapter 章、节
Application 应用
Activity 活动
Debug 调试
Compare 比较
Distance 区别、不同
Operator 操作
Struct 结构
Binary 二进制
|
n 自动加载各种资料,一站式搜索系统常见资料;
n 能够打开常见文档类资料,例如txt文件、word文件、pdf文件、Visio文件
n 能够打开常见图片资料,例如jpg格式文件、gif文件、png文件
n 能够打开常见音频资料和视频资料,例如avi文件、mp3文件
支持简单可用的类型扩展接口,易于实现更多文件类型的加载
相关文章推荐
- C#OOP之七 多态的学习和使用
- C#OOP之六 构造函数和析构函数
- C#OOP之六 构造函数和析构函数
- C#OOP之六 构造函数和析构函数
- C#小练习
- C#语言中的小知识点
- C# 事务异常TransactionScope处理
- C#反射
- 全双工音频播放器在c#中使用waveIn / waveOut api
- 使用C#实现顺序队列
- c#操作IIS站点
- C#进阶系列——AOP?AOP!
- C#入门教程(一)–.Net平台技术介绍、C#语言及开发工具介绍-打造C#学习教程
- c# 枚举Enum和int转换(不使用强转)
- C# MVC模式下商品抽奖功能实现
- (二)C# winform C/S WebBrowser qq第三方授权登录
- C# 位运算轻松实现权限操作
- C#反射学习笔记
- C# IsExistWindow函数写法及调用
- C# 委托如何理解 打个比喻