C# 什么是继承和派生

C# 什么是继承和派生

在 C# 中,继承(Inheritance)是一种机制,它允许一个类(子类)从另一个类(父类)中继承属性和方法。这种关系使得子类可以重用父类的代码,同时可以在子类中添加或修改属性和方法。继承有助于减少代码重复和提高代码的可维护性。

派生(Derivation)是指使用继承机制创建的子类。子类从父类继承而来,可以扩展或修改父类的功能。在 C# 中,派生类通常是通过使用关键字 classnew 关键字来创建的。

在一个子类继承多个父类的情况下,子类的实例化对象可以访问所有父类中被继承的内容。让我用一个比喻来解释一下。

假设你是一个魔法师,而这些父类就像是不同的魔法书。每本魔法书都包含了独特的咒语和技能(方法和属性)。当你作为一个子类继承了多个父类时,你就像是拥有了多本魔法书的超级魔法师!

因此,当你实例化一个子类的对象时,你可以通过该对象访问并使用所有继承自父类的方法和属性。无论这些方法和属性是来自第一个父类、第二个父类还是其他父类,都可以直接使用。这是因为子类会继承父类的方法和属性,并具备相应的功能。

// 定义一个父类
public class Animal
{
    protected string name;

    public virtual void Speak()
    {
        Debug.Log("我是动物。");
    }
}

// 定义一个子类,继承自父类Animal
public class Cat : Animal
{
    public override void Speak()
    {
        Debug.Log("我是一只猫咪,喵喵喵~");
    }

    public void Purr()
    {
        Debug.Log("猫咪正在发出呼噜声。");
    }
}

// 在游戏对象上附加该脚本
public class TestScript : MonoBehaviour
{
    private void Start()
    {
        // 实例化Cat类的对象
        Cat myCat = new Cat();

        // 调用继承自父类的方法
        myCat.Speak(); // 输出:我是一只猫咪,喵喵喵~

        // 调用子类自己新增的方法
        myCat.Purr(); // 输出:猫咪正在发出呼噜声。

        // 可以将子类对象赋值给父类引用
        Animal animal = myCat;

        // 通过父类引用调用继承自父类的方法
        animal.Speak(); // 输出:我是一只猫咪,喵喵喵~
    }
}

总结一下,当一个子类继承多个父类时,子类的实例化对象可以访问并使用所有继承自父类的方法和属性。它们就像是一个超级魔法师,可以利用所有魔法书中的咒语和技能。

在继承中,有一些内容是无法被子类继承的。以下是一些不可以被继承的内容:

  1. 构造函数(Constructor):子类会继承父类的方法和属性,但构造函数不会被继承。每个类都需要自己定义并实现自己的构造函数。

  2. 私有成员(Private Members):私有成员包括私有方法、私有属性和私有字段等,它们只能在声明它们的类内部访问,无法被子类继承。

  3. 静态成员(Static Members):静态成员属于类本身,而不属于类的实例。虽然子类可以访问父类的静态成员,但无法继承静态成员。

  4. 密封类(Sealed Class):如果一个类被声明为密封类,意味着它不能被其他类继承。因此,无法从密封类派生出子类。

  5. 重写修饰符(Override Modifier):使用 sealed 修饰符标记的方法无法被子类再次重写。

总结起来,构造函数、私有成员、静态成员、密封类以及被标记为 sealed 的重写方法都是不可被继承的。其他公共成员,包括公共方法、属性和字段等,都可以被子类继承并访问。

### 什么是C#中的继承继承是面向对象编程(OOP)的核心特性之一,它允许一个(称为派生或子继承另一个(称为基或父)的成员(如属性方法)[^2]。这种机制使得代码可以重用、扩展维护,同时保持结构清晰。 ### C#继承的基本特点 - **单继承**:C#仅支持单继承,即一个只能直接继承自一个基。然而,C#允许通过接口实现多重继承的效果[^2]。 - **继承的成员**:子可以继承的字段、属性、方法等,但构造函数不会被继承。子默认调用基的无参构造函数来初始化基部分。如果基没有无参构造函数,则需要显式调用基的构造函数[^4]。 - **访问修饰符影响继承**:基中成员的可访问性决定了它们是否可以被子继承。例如,`private`成员不会被继承,而`public``protected`成员可以被继承[^2]。 - **继承可以多层**:子可以从另一个子继承,从而形成继承链。这意味着继承可以隔代进行。 - **不允许循环继承**:C#不允许两个相互继承,即不能存在A继承B,同时B又继承A的情况。 ### C#继承的语法 在C#中,继承的语法如下: ```csharp <访问修饰符> class <基> { // 基成员 } class <派生> : <基> { // 派生成员 } ``` 例如,定义一个基 `Animal`,然后定义一个派生 `Dog`: ```csharp public class Animal { public void Eat() { Console.WriteLine("This animal eats food."); } } public class Dog : Animal { public void Bark() { Console.WriteLine("The dog barks."); } } ``` 在这个例子中,`Dog` 继承了 `Animal` 的 `Eat` 方法,并添加了自己的 `Bark` 方法。 ### 继承的作用 - **代码重用**:通过继承,可以避免重复编写相同的代码。子可以直接使用基已有的实现。 - **扩展性**:可以在不修改基的情况下,通过继承添加新的功能。 - **维护性**:如果基发生变化,所有继承自它的子都会自动继承这些变化,减少了维护成本[^2]。 ### 继承的条件 - **访问权限**:基中的成员必须具有适当的访问权限(如 `public` 或 `protected`),否则不能被继承。 - **构造函数处理**:子必须确保基的构造函数被正确调用,以初始化基的部分。如果基没有无参构造函数,子必须显式调用基的构造函数[^4]。 ### 示例说明 下面是一个简单的继承示例,展示了如何定义基派生: ```csharp using System; public class Vehicle { public string Brand { get; set; } public virtual void Start() { Console.WriteLine("Vehicle started."); } } public class Car : Vehicle { public int NumberOfDoors { get; set; } public override void Start() { Console.WriteLine("Car started."); } } class Program { static void Main() { Car myCar = new Car(); myCar.Brand = "Toyota"; myCar.NumberOfDoors = 4; myCar.Start(); // 输出 "Car started." } } ``` 在这个例子中,`Car` 继承了 `Vehicle` ,并重写了 `Start` 方法。此外,`Car` 还添加了自己的属性 `NumberOfDoors`[^2]。 ### 总结 C#中的继承机制为代码重用、扩展维护提供了强大的支持。通过单继承接口的结合,C#实现了灵活的面向对象设计,同时避免了多重继承带来的复杂性。理解继承的概念规则是掌握C#面向对象编程的关键[^2]。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Unity青子

难题的解决使成本节约,求打赏

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值