第二十一章:C# 继承

继承是面向对象编程(OOP)的核心概念之一,它允许我们创建一个新的类,该类从现有的类继承成员。通过继承,子类可以重用、扩展和修改父类的行为,从而提高代码的复用性和可维护性。C#中的继承使得代码更加模块化和组织化。

1. 继承的基本概念

在C#中,继承使用:符号表示。一个类只能继承一个直接父类(单继承),但可以实现多个接口。

示例:

public class Animal
{
    public void Eat()
    {
        Console.WriteLine("Eating...");
    }
}

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

class Program
{
    static void Main(string[] args)
    {
        Dog dog = new Dog();
        dog.Eat();  // 基类方法
        dog.Bark(); // 派生类方法
    }
}

在这个示例中,Dog类继承自Animal类,从而获得了Animal类的Eat方法,并添加了自己的Bark方法。

2. 重写基类方法

在子类中可以使用override关键字重写基类中的虚方法。基类中的方法需要使用virtual关键字标识为虚方法。

示例:

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

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

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

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

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

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

3. 基类构造函数

子类构造函数可以调用基类构造函数,以确保基类的部分正确初始化。可以使用base关键字调用基类的构造函数。

示例:

public class Animal
{
    public string Name { get; set; }

    public Animal(string name)
    {
        Name = name;
    }
}

public class Dog : Animal
{
    public Dog(string name) : base(name)
    {
    }

    public void Display()
    {
        Console.WriteLine($"Dog's name is: {Name}");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Dog dog = new Dog("Buddy");
        dog.Display(); // 输出 Dog's name is: Buddy
    }
}

在这个示例中,Dog类的构造函数调用了基类Animal的构造函数,并传递了参数。

4. 密封类和密封方法

在C#中,可以使用sealed关键字阻止类被继承,或者阻止方法在派生类中被重写。

密封类:

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

// 下面的代码将导致编译错误,因为Animal类是密封的
// public class Dog : Animal
// {
// }

密封方法:

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

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

// 下面的代码将导致编译错误,因为MakeSound方法是密封的
// public class Bulldog : Dog
// {
//     public override void MakeSound()
//     {
//         Console.WriteLine("Woof");
//     }
// }

在这些示例中,密封类不能被继承,密封方法不能被重写。

5. 抽象类

抽象类是不能实例化的类,它只能作为其他类的基类。抽象类可以包含抽象方法,这些方法必须在派生类中实现。抽象类使用abstract关键字定义。

示例:

public abstract class Animal
{
    public abstract void MakeSound();

    public void Sleep()
    {
        Console.WriteLine("Sleeping...");
    }
}

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

class Program
{
    static void Main(string[] args)
    {
        // Animal myAnimal = new Animal(); // 这将导致编译错误,因为Animal是抽象类
        Dog myDog = new Dog();
        myDog.MakeSound(); // 输出 Bark
        myDog.Sleep(); // 输出 Sleeping...
    }
}

在这个示例中,Animal类是一个抽象类,包含一个抽象方法MakeSound和一个具体方法SleepDog类继承自Animal类,并实现了MakeSound方法。

6. 接口与继承

一个类可以实现多个接口,而一个类只能继承一个基类。接口定义了一组方法和属性的契约,实现接口的类必须实现接口中的所有成员。

示例:

public interface IFlyable
{
    void Fly();
}

public interface IRunnable
{
    void Run();
}

public class Bird : IFlyable, IRunnable
{
    public void Fly()
    {
        Console.WriteLine("Flying...");
    }

    public void Run()
    {
        Console.WriteLine("Running...");
    }
}

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

在这个示例中,Bird类实现了IFlyableIRunnable接口,并实现了接口中的所有方法。

7. 接口的继承

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

示例:

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接口,并实现了所有继承的成员。

结束语

C#中的继承概念,包括类的继承、方法重写、基类构造函数、密封类和方法、抽象类、接口与继承、以及接口的继承。继承使得代码更加模块化和组织化,有助于代码的复用和维护。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值