C#的多态性

C#的多态性分为静态多态性和动态多态性。

一、静态多态性

在编译时,函数和对象的连接机制被称为早期绑定,也被称为静态绑定。C# 提供了两种技术来实现静态多态性。分别为:
1.函数重载
2.运算符重载

1.函数重载

可以在同一个范围内对相同的函数名有多个定义。函数的定义必须彼此不同,可以是参数列表中的参数类型不同,也可以是参数个数不同。不能重载只有返回类型不同的函数声明。
本质上是为使同一个类的方法在不同输入下能产生不同的输出,在类里面定义了数个不同内容(可能是输入的参数类型不同或输入的参数个数不同),但方法名相同的方法。
如下:
(1)

using System;
namespace PolymorphismApplication
{
    public class TestData  
    {  
        public int Add(int a, int b, int c)  
        {  
            return a + b + c;  
        }  
        public int Add(int a, int b)  
        {  
            return a + b;  
        }  
    }  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            TestData dataClass = new TestData();
            int add1 = dataClass.Add(1, 2);  
            int add2 = dataClass.Add(1, 2, 3);

            Console.WriteLine("add1 :" + add1);
            Console.WriteLine("add2 :" + add2);  
        }  
    }  
}

(2)

using System;
namespace PolymorphismApplication
{
   class Printdata
   {
      void print(int i)
      {
         Console.WriteLine("输出整型: {0}", i );
      }

      void print(double f)
      {
         Console.WriteLine("输出浮点型: {0}" , f);
      }

      void print(string s)
      {
         Console.WriteLine("输出字符串: {0}", s);
      }
      static void Main(string[] args)
      {
         Printdata p = new Printdata();
         // 调用 print 来打印整数
         p.print(1);
         // 调用 print 来打印浮点数
         p.print(1.23);
         // 调用 print 来打印字符串
         p.print("Hello Runoob");
         Console.ReadKey();
      }
   }
}

2.运算符重载

重定义运算符。operator声明。
C# 中运算符重载的能力:
C# 中运算符重载的能力

实例如下:

using System;

namespace OperatorOvlApplication
{
   class Box
   {
      private double length;      // 长度
      private double breadth;     // 宽度
      private double height;      // 高度

      public double getVolume()
      {
         return length * breadth * height;
      }
      public void setLength( double len )
      {
         length = len;
      }

      public void setBreadth( double bre )
      {
         breadth = bre;
      }

      public void setHeight( double hei )
      {
         height = hei;
      }
      // 重载 + 运算符来把两个 Box 对象相加
      public static Box operator+ (Box b, Box c)
      {
         Box box = new Box();
         box.length = b.length + c.length;
         box.breadth = b.breadth + c.breadth;
         box.height = b.height + c.height;
         return box;
      }

   }

   class Tester
   {
      static void Main(string[] args)
      {
         Box Box1 = new Box();         // 声明 Box1,类型为 Box
         Box Box2 = new Box();         // 声明 Box2,类型为 Box
         Box Box3 = new Box();         // 声明 Box3,类型为 Box
         double volume = 0.0;          // 体积

         // Box1 详述
         Box1.setLength(6.0);
         Box1.setBreadth(7.0);
         Box1.setHeight(5.0);

         // Box2 详述
         Box2.setLength(12.0);
         Box2.setBreadth(13.0);
         Box2.setHeight(10.0);

         // Box1 的体积
         volume = Box1.getVolume();
         Console.WriteLine("Box1 的体积: {0}", volume);

         // Box2 的体积
         volume = Box2.getVolume();
         Console.WriteLine("Box2 的体积: {0}", volume);

         // 把两个对象相加
         Box3 = Box1 + Box2;

         // Box3 的体积
         volume = Box3.getVolume();
         Console.WriteLine("Box3 的体积: {0}", volume);
         Console.ReadKey();
      }
   }
}

二、动态多态性

都采用override重写方法。

1.抽象类

C#允许把类和函数声明为abstract。
抽象类不能实例化,抽象类可以包含普通函数和抽象函数。
抽象函数就是只有函数定义没有函数体的函数。显然,抽象函数本身也是虚拟(Virtual)的。
类是一个模板,那么抽象类就是一个不完整的模板。我们自然不可以使用不完整的模板去构造对象。
抽象类的声明如下:

abstract class Building
{
    public abstract decimal CalculateHeatingCost();
}

注意:
(1)当一个类中如果有方法被声明为abstract时,这个类也要被声明为abstract。
(2)当继承一个抽象类时,必须去实现抽象方法(就是填充函数内容)。
(3)可以用抽象类去声明,但是不能用抽象类去构造。
(4)在抽象方法声明中不能使用​​static​​或​​virtual​​修饰符。

抽象类的使用如下:

using System;
namespace PolymorphismApplication
{
	//抽象类
	abstract class Bird
	{  //含有抽象方法,就一定是抽象类
    	private float speed;

    	public abstract void Fly();   //抽象方法
    }

	//派生类
	class Crow : Bird
	{  //继承了抽象类,此时必须要求实现抽象方法
	    public override void Fly()  //override重写方法
	    {
	        Console.WriteLine("Crow is flying!");
	    }
	}
   	class RectangleTester
	{
	      static void Main(string[] args)
          {
			//用派生类构造和声明
			Crow crow = new Crow;
			crow.Fly();
			
			//用抽象类声明,用派生类构造
			Bird bird = new Crow();
			bird.Fly();
          }
     }

}

2.虚方法

virtual声明,override重写。
与抽象类的区别:

虚方法抽象方法
用virtual修饰用abstract修饰
要用方法体,哪怕是一个分号不允许有方法体
可以被子类override(重写)必须被子类override(重写)
除了密封类都可以写只能在抽象类中

虚方法可以在不同的继承类中有不同的实现:

using System;
using System.Collections.Generic;

public class Shape
{
    public int X { get; private set; }
    public int Y { get; private set; }
    public int Height { get; set; }
    public int Width { get; set; }
   
    // 虚方法
    public virtual void Draw()
    {
        Console.WriteLine("执行基类的画图任务");
    }
}

class Circle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("画一个圆形");
        base.Draw();
    }
}
class Rectangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("画一个长方形");
        base.Draw();
    }
}
class Triangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("画一个三角形");
        base.Draw();
    }
}

class Program
{
    static void Main(string[] args)
    {
        // 创建一个 List<Shape> 对象,并向该对象添加 Circle、Triangle 和 Rectangle
        var shapes = new List<Shape>
        {
            new Rectangle(),
            new Triangle(),
            new Circle()
        };

        // 使用 foreach 循环对该列表的派生类进行循环访问,并对其中的每个 Shape 对象调用 Draw 方法
        foreach (var shape in shapes)
        {
            shape.Draw();
        }

        Console.WriteLine("按下任意键退出。");
        Console.ReadKey();
    }

}

参考资料链接:
https://blog.csdn.net/lym940928/article/details/79841135
https://www.runoob.com/csharp/csharp-polymorphism.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值