第二十二章:C# 多态性

多态性是面向对象编程(OOP)的一个重要特性,它允许一个接口有多个实现方式。在C#中,多态性主要通过方法重写(Override)和接口实现来实现。理解多态性有助于编写更灵活和可扩展的代码。

1. 方法重写(Override)

方法重写是多态性的一个重要表现形式,它允许子类提供特定的实现来替代基类中的方法。基类中的方法必须使用virtual关键字标记为虚方法,子类使用override关键字来重写该方法。

示例:

public class Animal
{
    public virtual void MakeSound()
    {
        Console.WriteLine("Some generic animal sound");
    }
}

public class Dog : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("Bark");
    }
}

public class Cat : Animal
{
    public override void MakeSound()
    {
        Console.WriteLine("Meow");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Animal myAnimal = new Animal();
        myAnimal.MakeSound(); // 输出 Some generic animal sound

        Dog myDog = new Dog();
        myDog.MakeSound(); // 输出 Bark

        Cat myCat = new Cat();
        myCat.MakeSound(); // 输出 Meow

        Animal anotherDog = new Dog();
        anotherDog.MakeSound(); // 输出 Bark
    }
}

在这个示例中,DogCat类重写了Animal类的MakeSound方法,展示了多态性的特性。

2. 抽象类与抽象方法

抽象类不能被实例化,通常作为其他类的基类。抽象方法没有实现,必须在派生类中重写。抽象类使用abstract关键字定义,抽象方法也使用abstract关键字定义。

示例:

public abstract class Shape
{
    public abstract double GetArea();

    public void DisplayArea()
    {
        Console.WriteLine($"Area: {GetArea()}");
    }
}

public class Circle : Shape
{
    public double Radius { get; set; }

    public Circle(double radius)
    {
        Radius = radius;
    }

    public override double GetArea()
    {
        return Math.PI * Radius * Radius;
    }
}

public class Rectangle : Shape
{
    public double Width { get; set; }
    public double Height { get; set; }

    public Rectangle(double width, double height)
    {
        Width = width;
        Height = height;
    }

    public override double GetArea()
    {
        return Width * Height;
    }
}

class Program
{
    static void Main(string[] args)
    {
        Circle circle = new Circle(5);
        circle.DisplayArea(); // 输出 Area: 78.53981633974483

        Rectangle rectangle = new Rectangle(4, 5);
        rectangle.DisplayArea(); // 输出 Area: 20
    }
}

在这个示例中,CircleRectangle类继承自Shape抽象类,并实现了GetArea方法。

3. 接口与多态性

接口定义了一个类应该具有的一组方法和属性,但不提供具体实现。实现接口的类必须提供接口中定义的所有成员的实现。接口实现也是多态性的一种表现形式。

示例:

public interface IAnimal
{
    void MakeSound();
}

public class Dog : IAnimal
{
    public void MakeSound()
    {
        Console.WriteLine("Bark");
    }
}

public class Cat : IAnimal
{
    public void MakeSound()
    {
        Console.WriteLine("Meow");
    }
}

class Program
{
    static void Main(string[] args)
    {
        IAnimal myDog = new Dog();
        myDog.MakeSound(); // 输出 Bark

        IAnimal myCat = new Cat();
        myCat.MakeSound(); // 输出 Meow
    }
}

在这个示例中,DogCat类实现了IAnimal接口,并提供了MakeSound方法的具体实现。

4. 接口与继承

接口可以继承其他接口,这使得接口更加灵活和可重用。

示例:

public interface IAnimal
{
    void Eat();
}

public interface IFlyable : IAnimal
{
    void Fly();
}

public class Bird : IFlyable
{
    public void Eat()
    {
        Console.WriteLine("Eating...");
    }

    public void Fly()
    {
        Console.WriteLine("Flying...");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Bird bird = new Bird();
        bird.Eat(); // 输出 Eating...
        bird.Fly(); // 输出 Flying...
    }
}

在这个示例中,IFlyable接口继承了IAnimal接口,Bird类实现了IFlyable接口,并提供了所有继承成员的实现。

5. 多态性的优势

多态性提高了代码的灵活性和可扩展性。通过使用基类引用或接口引用,可以编写更通用的代码,减少代码的重复,并且可以轻松地扩展新功能。

示例:

public abstract class Shape
{
    public abstract double GetArea();
}

public class Circle : Shape
{
    public double Radius { get; set; }

    public Circle(double radius)
    {
        Radius = radius;
    }

    public override double GetArea()
    {
        return Math.PI * Radius * Radius;
    }
}

public class Rectangle : Shape
{
    public double Width { get; set; }
    public double Height { get; set; }

    public Rectangle(double width, double height)
    {
        Width = width;
        Height = height;
    }

    public override double GetArea()
    {
        return Width * Height;
    }
}

class Program
{
    static void Main(string[] args)
    {
        List<Shape> shapes = new List<Shape>
        {
            new Circle(5),
            new Rectangle(4, 5)
        };

        foreach (Shape shape in shapes)
        {
            Console.WriteLine($"Area: {shape.GetArea()}");
        }
    }
}

在这个示例中,我们创建了一个包含不同形状对象的列表,并通过基类引用调用GetArea方法,展示了多态性的优势。

6. 多态性与泛型

多态性可以与泛型结合使用,进一步提高代码的灵活性和可重用性。

示例:

public interface IShape
{
    double GetArea();
}

public class Circle : IShape
{
    public double Radius { get; set; }

    public Circle(double radius)
    {
        Radius = radius;
    }

    public double GetArea()
    {
        return Math.PI * Radius * Radius;
    }
}

public class Rectangle : IShape
{
    public double Width { get; set; }
    public double Height { get; set; }

    public Rectangle(double width, double height)
    {
        Width = width;
        Height = height;
    }

    public double GetArea()
    {
        return Width * Height;
    }
}

public class ShapePrinter<T> where T : IShape
{
    public void PrintArea(T shape)
    {
        Console.WriteLine($"Area: {shape.GetArea()}");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Circle circle = new Circle(5);
        Rectangle rectangle = new Rectangle(4, 5);

        ShapePrinter<Circle> circlePrinter = new ShapePrinter<Circle>();
        circlePrinter.PrintArea(circle); // 输出 Area: 78.53981633974483

        ShapePrinter<Rectangle> rectanglePrinter = new ShapePrinter<Rectangle>();
        rectanglePrinter.PrintArea(rectangle); // 输出 Area: 20
    }
}

在这个示例中,我们定义了一个泛型类ShapePrinter,它可以打印实现了IShape接口的任何形状的面积。

结束语

C#中的多态性概念,包括方法重写、抽象类与抽象方法、接口与多态性、接口继承、多态性的优势以及多态性与泛型的结合。

  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值