C#的多态

多态

C#中的多态是指一个实体可以有多种形态。它主要体现在:

  1. 继承
    子类可以重写父类的方法,实现不同的功能,这就是多态性。
  2. 接口
    实现同一个接口的不同类,对同一个方法可以有不同实现。
  3. 虚方法
    使用virtual和override关键字实现方法的重写。
  4. 抽象类和接口
    抽象类和接口定义标准但不实现具体行为,留给派生类实现。
  5. 多态使用
    父类引用可以指向子类对象,在调用方法时自动选择子类版本。
  6. 只能访问父类接口
    通过父类引用只能访问父类中的成员,不知道具体子类。
  7. 动态绑定
    调用时根据对象实际类型选择方法实现版本,这是多态的关键。
    所以C#多态主要通过继承、接口和虚方法实现子类重写,利用父类引用来调用方法产生不同效果。它可以提高程序的可扩展性和重用性。

虚方法实现多态

虚方法(Virtual Method)是一种允许子类重写的方法,虚方法用于建立基类和子类之间的多态性关系。

在基类中,可以使用 virtual 关键字来定义一个虚方法。虚方法可以被子类重写,子类可以通过 override 关键字来重写基类中的虚方法。

常见的虚方法:ToString() Equals()

// 基类
public class Animal
{
public virtual void Eat()
{
Console.WriteLine("Animal is eating...");
}
}

// 派生类
public class Dog : Animal
{
public override void Eat()
{
Console.WriteLine("Dog is eating dog food...");
}
}

public class Cat : Animal
{
public override void Eat()
{
Console.WriteLine("Cat is eating fish...");
}
}

class Program
{
static void Main(string[] args)
{
Animal dog = new Dog();
Animal cat = new Cat();

dog.Eat(); // 输出:Dog is eating dog food...
cat.Eat(); // 输出:Cat is eating fish...

Animal animal = new Animal();
animal.Eat(); // 输出:Animal is eating...
}
}

抽象类实现多态

使用抽象类实现多态的主要特征是:

抽象类中定义抽象方法,不提供实现细节。

派生类必须实现抽象基类中的所有抽象方法。

派生类可以自由实现方法的细节。

// 定义一个简单的形状接口
public abstract class Shape
{
public abstract void Draw();
}

// 具体圆形类
public class Circle : Shape
{
public override void Draw()
{
Console.WriteLine("Drawing a circle");


// 实现圆的绘制逻辑
DrawCircle(); 
}

private void DrawCircle()
{
// 实际绘制圆的代码
}
}

// 具体矩形类
public class Rectangle : Shape
{
public override void Draw()
{
Console.WriteLine("Drawing a rectangle");


// 实现矩形的绘制逻辑
DrawRectangle();
}

private void DrawRectangle()
{
// 实际绘制矩形的代码
}
}

class Program
{
public static void Main(string[] args)
{
List<Shape> shapes = new List<Shape>();
shapes.Add(new Circle());
shapes.Add(new Rectangle());

foreach (Shape shape in shapes)
{
  shape.Draw(); 
}
}
}

虚方法和抽象类实现多态的对比

  1. 如果父类中的方法有默认的实现,并且父类需要被实例化,这时可以考虑将父类定义成一个普通类,用虚方法来实现多态。
  2. 如果父类中的方法没有默认实现,父类也不需要被实例化,则可以将该类定义为抽象类。

接口

接口是一种规范,只要一个类实现了一个接口,这个类就必须实现这个接口中所有的成员。

基本语法:interface关键字声明接口,接口中可以有属性、方法,没有实现

接口所有成员默认为public

接口的名称通常以“I”开头,如IList

[访问修饰符] interface 接口名
{
    // 接口成员定义
}

public interface IBusiness
{
    void GetMoney();
}

public interface IGovernment
{
    void GetPower();
}  

如果一个类即继承了类又实现了接口,那么类必须写在前面。一个类只能继承一个父类,但可以实现多个接口
public interface IBusiness: All
    {
        void GetMoney();
    }

    public interface IGovernment: All
    {
        void GetPower();
    }

    public interface All
    {
        void EveryThing();
        int Every
        {
            get; set;
        }
        double Much { get; }
    }

接口和抽象类的区别

  1. 实现方式:接口只能声明方法,属性和事件的签名,不能有实现,而抽象类可以包含抽象方法和具体方法。
  2. 实现限制:一个类可以实现多个接口,但只能继承一个抽象类。
  3. 构造函数:抽象类可以有构造函数,而接口不能有构造函数。
  4. 访问修饰符:接口中的方法和属性默认为公共的,可以为public、internal、protected,而抽象类可以有任何访问修饰符。
  5. 用途:接口用于定义一组必须实现的方法和属性,以确保类实现了特定的行为。抽象类用于定义一个模板类,其中包含了一些通用方法和属性,需要在派生类中实现。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值