C#多态性

C#多态性

什么是多态

多态是同一个行为具有多个不同表现形式或形态的能力

多态性意味着有多重形式。在面向对象编程范式中,多态性往往表现为“一个接口,多个功能”

多态性分为静态和动态。

静态多态性:函数的响应是在编译时发生的。

动态多态性:函数的响应实在运行时发生的。

在C#中,每个类型都是多态的,因为包括用户自定义类型在内的所有类型,都继承于Object

静态多态性

在编译时,函数和对象的连接机制被称为早期绑定,也被称为静态绑定。

C#提供了两种技术来实现静态多态性。分别是:
函数重载
运算符重载

函数重载

我们可以在同一个范围内对相同的函数名有多个定义。函数的定义必须彼此不同,可以是参数列表中的参数类型不同,也可以是参数个数不同,但是不能重载只有返回类型不同的函数声明。

即:函数重载只与参数类型和个数有关,与函数返回值类型无关

实例如下:

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);  
        }  
    }  
}

运算符重载

我们可以重定义或重载C#中内置的运算符。
程序员也可以使用用户自定义类型的运算符。
重载运算符时具有特殊名称的函数,时通过关键字operator后跟运算符的符号来定义的。
与其他函数一样,重载运算符有返回类型和参数列表。

运算符重载就是给某一些运算符赋予新的计算逻辑,运算符重载就是一个方法。

运算符重载的要求

1.访问权限必须时public
2.方法必须是static
3.在运算符重载中,必须有operator来修饰
4.返回值类型可以是除了void之外的任意类型
5.参数限制:
(1)参数列表中,至少要包含一个当前类型。
(2)参数的数量不是随意的,要和运算符能够操作的运算数量匹配。
(3)三元运算符不允许重载。

可以重载的运算符

可以重载的运算符:
+、-、*、/、%、++、–;&、|、!、^;~、>、<、>=、<=、==、!=

关系运算符要是重写的话,需要成对重写,否则会在运算符处报错。

运算符重载的语法
public static [返回值类型] operator [运算符]  
{
    
}
运算符重载实例

实例1:

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();
      }
   }
}

实例2:


    class Program
    {
        static void Main(string[] args)
        {
            BoxCompute tmp = new BoxCompute();
            tmp.length = 10;
            tmp.width = 20;
            tmp.height = 30;

            BoxCompute tmp2 = 2 * tmp ;
            Console.WriteLine(tmp2.length);
        }
    }

class BoxCompute
    {
        public float length;
        public float width;
        public float height;

        /// <summary>
        /// 计算箱子 体积
        /// </summary>
        /// <returns></returns>
        public static float BoxComputeVolume(float length,float width,float height)
        {
            return length * width * height;
        }

        /// <summary>
        /// 计算箱子 面积之和
        /// </summary>
        /// <returns></returns>
        public static float BoxComputeAreaTotal(float length,float width,float height)
        {
            return length * width * 2 + length * height * 2 + width * height * 2;
        }
        /// <summary>
        /// 计算两个箱子长宽高相加之后的箱子 
        /// </summary>
        /// <param name="firstBox"></param>
        /// <param name="secondBox"></param>
        /// <returns></returns>
        public static BoxCompute operator +(BoxCompute firstBox,BoxCompute secondBox)
        {
            BoxCompute result = new BoxCompute();
            result.length = firstBox.length + secondBox.length;
            result.width = firstBox.width + secondBox.width;
            result.height = firstBox.height + secondBox.height;

            return result;
        }

        /// <summary>
        /// 箱子长宽高等比缩放
        /// </summary>
        /// <param name="multipleNum"></param>
        /// <param name="tmpBox"></param>
        /// <returns></returns>
        public static BoxCompute operator *(float multipleNum, BoxCompute tmpBox)
        {
            BoxCompute result = new BoxCompute();
            result.length = tmpBox.length * multipleNum;
            result.width = tmpBox.width * multipleNum;
            result.height = tmpBox.height * multipleNum;

            return result;
        }
    }
}

动态多态性

多态的本质就是:父类的引用可以指向子类的对象

方法的隐藏和重写

在动态多态性中,一定会涉及到方法的隐藏和重写

方法的隐藏

在父类和子类中有相同的方法时,子类会自动隐藏父类中的方法

方法的重写

关键字:virture-虚
用来修饰方法。
作用:
虚方法可以被子类隐藏,也可以被重写;
非虚方法只能被子类隐藏,不能被重写

关键字:override -重写
重写:又叫覆写,指的是将父类的方法重新实现

所以,要想对方法重写,那么必须将原方法改为虚方法:即在原方法上加上virture关键字即可。然后在子类中重写的时候,需要在子类的方法中加上override关键字修饰

注意:只有虚方法或者抽象方法(abstract)才能够重写

抽象类

关键字:abstract
抽象类:用abstract修饰的类就是抽象类。
抽象类的特点:

1.抽象类不能实例化对象(与静态类相似)。
2.抽象类中可以写非静态成员(与静态类相反)。
3.抽象类可以继承,所以非静态成员是给子类用的。

C#允许使用关键字abstract创建抽象类,用于提供接口的部分类的实现。
当一个派生类集成自该抽象类时,实现即完成。
抽象类包含抽象方法,抽象方法可以被派生类实现。派生类具有更专业的功能。

抽象类的规则

1.不能创建一个抽象类的实例
2.不能再一个抽象类外部声明一个抽象方法
3.通过类定义前面放置关键字sealed,可以将类声明为密封类。当一个类被声明为sealed时,它不能被继承。所以抽象类不能被声明为sealed

抽象类的实例
 class Program
    {
        static void Main(string[] args)
        {
            
            Box box = new Box();
            box.length = 10;
            box.width = 20;
            box.height = 30;
            Console.WriteLine("该箱子的体积是:"+box.Volume());
            //输出为: 该箱子的体积为:6000
    
            Sphere sphere = new Sphere();
            sphere.radius = 22;
            Console.WriteLine("该球体的体积是:"+sphere.Volume());
            //输出为: 该球体的体积为:44602.24
        }
    }    
 abstract class Sharp
    {
        public int length;
        public int width;
        public int height;

        public float radius;

        public abstract float Volume();
    }

    class Box : Sharp
    {
        //override是重写,只有abstract和virture修饰的方法,才能在子类中重写
        public override float Volume()
        {
            float volume = this.length * this.width * this.height;
            return volume;
        }
    }

    class Sphere : Sharp
    {
        public override float Volume()
        {
            float volume =(float)( Math.Pow(this.radius, 3) * Math.PI * 4 / 3);
            return volume;
        }
    }

普通类

普通类的多态性

相比较于抽象类,没有抽象类多态的限制

普通类不需要一定实现父类中的方法,而实现抽象类的则必须实现抽象父类中的抽象方法

普通类的多态实例
 class Program
    {
        static void Main(string[] args)
        {
           
            Person person = new Person();
            Dog dog = new Dog();
            person.ShowAnimalClass();
            dog.ShowAnimalClass();
        }
    }    
class Animal
    {
        public bool gender;
        public int age;
        public string animalClass;

        public void ShowGender()
        {
            Console.WriteLine("性别为:"+this.gender);
        }
        public void ShowAge()
        {
            Console.WriteLine("年龄为:"+this.age);
        }
        public void ShowAnimalClass()
        {
            Console.WriteLine("动物种类为:"+this.animalClass);
        }
    }
   class Person : Animal
    {
        public Person()
        {
            this.animalClass = "人类";
        }
        //方法的隐藏
        public void ShowGender()
        {
            Console.WriteLine("隐藏父类中的ShowGender方法"+":默认男的");
        }
        //方法的隐藏
        public new void  ShowAge()
        {
            Console.WriteLine("就不告诉你");
        }
    }
    class Dog : Animal
    {
        public Dog()
        {
            this.animalClass = "犬科";
        }
    }
  • 2
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值