首先理解一下什么叫多态。同一操作作用于不同的对象,可以有不同的解释,产生不同的执行结果,这就是多态性。
多态性通过派生类覆盖基类中的虚函数型方法来实现。
多态性分为两种,一种是编译时的多态性,一种是运行时的多态性。
编译时的多态性:编译时的多态性是通过重载来实现的。对于非虚的成员来说,系统在编译时,根据传递的参数、返回的类型等信息决定实现何种操作。
运行时的多态性:运行时的多态性就是指直到系统运行时,才根据实际情况决定实现何种操作。C#中运行时的多态性是通过覆盖虚成员实现。
举例:
using System;
public class DrawingBase
{
public virtual void Draw()
{
Console.WriteLine("I'm just a generic drawing object.");
}
}
public class Line : DrawingBase
{
public override void Draw()
{
Console.WriteLine("I'm a Line.");
}
}
public class Circle : DrawingBase
{
public override void Draw()
{
Console.WriteLine("I'm a Circle.");
}
}
public class Square : DrawingBase
{
public override void Draw()
{
Console.WriteLine("I'm a Square.");
}
}
public class DrawDemo
{
public static int Main(string[] args)
{
DrawingBase[] dObj = new DrawingBase[4];
dObj[0] = new Line();
dObj[1] = new Circle();
dObj[2] = new Square();
dObj[3] = new DrawingBase();
foreach (DrawingBase drawObj in dObj)
drawObj.Draw();
return 0;
}
}
下面我们来分别说明一下多态中涉及到的四个概念:重载,覆盖,虚方法和抽象方法。
4.1 重载 在面对对象这样的高级语言中都允许我们在一个类中定义多个方法名相同、方法间参数个数和参数顺序不同的方法,对于参数个数不同或者参数列表不同的情况我们称之为参数列表不同。需要注意的是这里没有提到方法的返回值。
特点(两必须一可以)
方法名必须相同
参数列表必须不相同
返回值类型可以不相同
public int Calculate(int x, int y)
public double Calculate(double x, double y)
举例:
public class Test
{
public int Calculate(int x, int y)
{
return x + y;
}
public double Calculate(double x, double y)
{
return x + y;
}
}
4.2 覆盖 子类中,为满足自己的需要来重复定义某个方法的不同实现。
定义:通过使用关键字override来覆盖
public override bool abc(...)
注意:只有虚方法和抽象方法才能被覆盖
要求:
*相同的方法名称
*相同的参数列表
*相同的返回值类型
例:
public class Test
{
public virtual int Calculate(int x, int y)
{
return x + y;
}
public virtual double Calculate(double x, double y)
{
return x + y;
}
}
派生类(子类)
public class TestOverride : Test
{
public override int Calculate(int x, int y)
{
return x * y;
}
public override double Calculate(double x, double y)
{
return x * y;
}
}
首先看这个类,我们在同一个类中满足了重载的三个特点,方法名必须相同Calculate;参数列表必须不相同第一个方法的两个参数类型为int类型,第二个方法的两个参数类型为double类型;返回值类型可以不相同一个返回值类型为int,另一个返回值类型为double。
4.3虚方法
当类中的方法声明前加上了virtual修饰符,我们称之为虚方法,反之为非虚。使用了virtual修饰符后,不允许再有static,abstract,或override修饰符。
对于非虚的方法,无论被其所在类的实例调用,还是被这个类的派生类的实例调用,方法的执行方式不变。而对于虚方法,它的执行方式可以被派生类改变,这种改变是通过方法的重载来实现的。
特点:
●声明使用virtual关键字。
●调用虚方法,运行时将确定调用对象是什么类的实例,并调用适当的覆写的方法。
●虚方法可以有实现体。
下面的例子说明了虚方法与非虚方法的区别。
例子:
using System;
class A
{
public void F() { Console.WriteLine("A.F"); }
public virtual void G() { Console.WriteLine("A.G"); }
}
class B : A
{
new public void F() { Console.WriteLine("B.F"); }
public override void G() { Console.WriteLine("B.G"); }
}
class Tese
{
static void Main()
{
B b = new B();
A a = b;
a.F();
b.F();
a.G();
b.G();
}
}
例子中,A类提供了两个方法:非虚的F和虚方法G.类B则提供了一个新的非虚的方法F,从而覆盖了继承的F;类B同时还重载了继承的方
法G.那么输出应该是:
A.F
B.F
B.G
B.G
注意到本例中,方法a.G()实际调用了B.G,而不是A.G.这是因为编译时值为A,但运行时值为B,所以B完成了对方法的实际调用.
4.4抽象类与方法
抽象类具有以下特性:
●抽象类不能实例化。使用override关键字可在派生类中实现抽象方法,经override声明重写的方法,其签名必须与override方法的签名一致。
●抽象类可以包含抽象方法和抽象访问器。
●不能用 sealed 修饰符修改抽象类,这意味着该类不能被继承。
从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实实现。
在方法或属性声明中使用 abstract 修饰符以指示此方法或属性不包含实现。
抽象方法具有以下特性:
●抽象方法是隐式的 virtual 方法。
●只允许在抽象类中使用抽象方法声明。
因为抽象方法声明不提供实实现,所以没有方法体;方法声明只是以一个分号结束,并且在签名后没有大括号 ({ })。例如:
public abstract void MyMethod();
●实现由 overriding 方法提供,它是非抽象类的成员。
●在抽象方法声明中使用 static 或 virtual 修饰符是错误的。
除了在声明和调用语法上不同外,抽象属性的行为与抽象方法一样。
●在静态属性上使用 abstract 修饰符是错误的。
●在派生类中,通过包括使用 override 修饰符的属性声明可以重写抽象的继承属性。
抽象类必须为所有接口成员提供实现。即如果父类被声明为抽象类,并存在未实现的抽象方法,那么子类就必须实现父类中所有的abstract成员,除非该类也是抽象的。
举例:
using System;
using System.Collections.Generic;
using System.Text;
namespace ConsoleApplication1
{
/// <summary>
/// 抽象类hcedar
/// </summary>
abstract class hcedar
{
/// <summary>
/// 抽象方法SayHello
/// </summary>
abstract public void SayHello();
/// <summary>
/// 抽象属性Hello
/// </summary>
abstract public string Hello
{
get;
set;
}
public void SayAbstract()
{
Console.WriteLine("this is a abstract!");
}
}
/// <summary>
/// hcedar2类,继承hcedar
/// </summary>
class hcedar2 : hcedar
{
public string _hello;
/// <summary>
/// Hello属性及其实现
/// </summary>
override public string Hello
{
get
{
return _hello;
}
set
{
_hello = value;
}
}
/// <summary>
/// SayHello方法及其实现
/// </summary>
override public void SayHello()
{
Console.WriteLine(Hello);
}
}
class Program
{
public static void Main()
{
hcedar2 h = new hcedar2();
h.Hello="Hello World!";
h.SayHello();
h.SayAbstract();
}
}
/*结果:
Hello World!
this is a abstract!
请按任意键继续. . .
*/
}
<script type="text/javascript"><!--
google_ad_client = "pub-6770445892601887";
/* 468x60, 创建于 09-11-19 */
google_ad_slot = "4437639877";
google_ad_width = 468;
google_ad_height = 60;
//-->
</script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js">
</script>
分享到:
相关推荐
多态是指一个行为具有多个不同表现形式的能力,在C#中通过多态性的检测时机可以分为静态多态性和动态多态性 静态多态性:函数重载和运算符重载 动态多态性:抽象方法、重写方法、隐藏方法 二:函数重载(overlode) ...
在C#语言中,多态性是一种非常强大的特性,它允许程序员编写更加灵活和可扩展的代码。本文将深入探讨C#中的多态性,并通过具体的示例来帮助读者更好地理解和应用这一特性。 #### 1. 多态性的定义 多态性是指允许...
### C#中的多态性详解 #### 一、多态性的概念 在C#中,多态性(Polymorphism)是一种重要的面向对象编程特性,它允许子类重写或扩展父类的方法,从而实现同一接口的不同实现方式。多态性意味着一个接口可以具有...
**C#多态性实验报告详细讲解** C#是一种面向对象的编程语言,其中多态性是其核心特性之一。本实验报告旨在深入理解和实践C#中的多态性,通过设计一个银行卡类(BankCard)及其派生类(ForeignCard,LimitedCard),...
在静态多态性中,函数的响应是在编译时发生的。 函数重载是静态多态性的一个重要实现方式。函数重载允许在同一个范围内对相同的函数名有多个定义。函数的定义必须彼此不同,可以是参数列表中的参数类型不同,也可以...
描述虚函数与飞虚函数的区别,以及多态的使用
C#中的多态性是面向对象编程的核心特性之一,它允许一个类的对象可以被视为它的基类类型或实现的接口类型。这种能力使得代码更加灵活,能够处理不同类型的对象,而无需知道具体的类型细节。在C#中,每种类型都具有多...
综上所述,这个"C#多态性实例,向基类构造函数传递参数"的示例展示了如何在C#中利用多态性、继承和构造函数来创建灵活、可扩展的代码结构。通过理解和应用这些概念,开发者可以编写出更高效、更具维护性的软件系统。
在C#编程语言中,多态性(Polymorphism)是面向对象编程的三大特性之一,其他两个是封装和继承。多态性允许我们使用一个通用的接口来处理不同的对象,使得代码更具可读性和可扩展性。在这个实例中,我们将深入探讨...
在C#应用程序开发中,多态性是一项核心概念,它允许不同的对象对同一行为做出不同的响应,从而展现出不同的行为特征。多态性是面向对象编程的三大特性之一,另外两个是封装和继承。多态性使得代码更具通用性和可扩展...
第一种:编译时的多态性,直接这样说不知道说啥?程序执行过程主要分为三步:编译,链接,运行。...C#运行时的多态性通过虚方法实现。在类方法声明加上了virtual修饰符,称为虚方法,反之为非虚方法
在C#编程语言中,多态性(Polymorphism)是一项核心特性,它允许我们使用一个接口或基类引用不同的派生类型。多态性在面向对象编程中扮演着至关重要的角色,因为它提供了代码的灵活性、可重用性和扩展性。下面我们将...
在这一系列“跳水在面向对象编程”的这篇...抽象类起到多态性和继承一个不同的和非常有趣的角色。我们将讨论抽象类与我们的动手实验和理论作为解释什么输出我们得到的所有方面。我们也将列出下来点,记得在文章的结尾。
C#教学课件:继承与多态性.ppt
在C#中,多态性分为两种类型:编译时的多态性和运行时的多态性。编译时的多态性主要通过方法重载实现,即在同一作用域内,用相同的名称但参数列表不同的方法。编译器根据传入的参数类型和数量自动选择正确的方法执行...
在C#中,多态性(Polymorphism)是面向对象编程的核心概念之一,它允许一个接口或基类引用调用不同的实现,从而提供更大的灵活性和代码重用。多态性分为编译时多态性和运行时多态性。 1. 编译时多态性: 编译时多态...
在C#中,面向对象的编程涉及几个核心概念,其中包括继承性、多态性和命名空间。这些特性使得代码更加灵活,易于维护,同时增强了模块的复用性。 **1. 继承机制** 继承是面向对象编程的一个关键特性,它允许一个类...