C#中子类调用父类的实现方法

本文介绍子类调用父类的方法,包括通过子类无参、有参构造函数创建实例时默认调用父类无参构造函数,在子类构造函数中用特定方式指明调用父类有参构造函数,以及通过子类设置父类公共属性,这些做法在分层架构设计中有应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

本文实例讲述了C#中实现子类调用父类的方法,分享给大家供大家参考之用。具体方法如下:

public class Person
{
    public Person()
    {
      Console.WriteLine("我是人");
    }
}
public class Student : Person
{
    public Student()
    {
      Console.WriteLine("我是学生");
    }
}

在客户端通过子类无参构造函数创建子类实例。

class Program
{
    static void Main(string[] args)
    {
      Student student = new Student();
      Console.ReadKey();
    }
}

输出结果:

我是人
我是学生

可见:通过调用子类无参构造函数创建子类实例,会默认调用父类无参构造函数。
如果把父类的无参构造函数去掉,会怎样呢?

–结果会报"Person不包含0个参数的构造函数"错。

二、通过子类有参构造函数创建子类实例

再同时为子类和父类添加有参构造函数。

public class Person
{
    public Person()
    {
      Console.WriteLine("我是人");
    }
    public Person(string name)
    {
      Console.WriteLine("我是人,我的名字叫{0}", name);
    }
}
public class Student : Person
{
    public Student()
    {
      Console.WriteLine("我是学生");
    }
    public Student(string name)
    {
      Console.WriteLine("我是学生,我的名字叫{0}", name);
    }
}

在客户端通过子类有参构造函数创建子类实例。

Student student = new Student("小明");
Console.ReadKey();

输出结果:输出结果:

我是人
我是学生,我的名字叫小明

可见:通过调用子类有参构造函数,同样默认会调用父类无参构造函数。

三、在子类中明确指出调用哪个父类构造函数

以上,默认调用了父类的无参构造函数,但如何调用父类的有参构造函数呢?

–在子类中使用base

在子类Student中的有参构造函数中使用base,明确调用父类有参构造函数。

public class Student : Person
{
    public Student()
    {
      Console.WriteLine("我是学生");
    }
    public Student(string name)
      : base(name)
    {
      Console.WriteLine("我是学生,我的名字叫{0}", name);
    }
}

客户端

Student student = new Student("小明");
Console.ReadKey();

输出结果:

我是人,我的名字叫小明
我是学生,我的名字叫小明

四、通过子类设置父类的公共属性

在父类Person中增加一个Name公共属性,并在父类的构造函数中对Name属性赋值。

public class Person
{
    public string Name { get; set; }
    public Person()
    {
      Console.WriteLine("我是人");
    }
    public Person(string name)
    {
      this.Name = name;
      Console.WriteLine("我是人,我的名字叫{0}", name);
    }
}

在客户端:

Student student = new Student("小明");
Console.WriteLine("子类获取父类的Name属性值为{0}", student.Name);
Console.ReadKey();  

输出结果:

我是人,我的名字叫小明
我是学生,我的名字叫小明 
子类获取父类的Name属性值为小明

以上代码的执行路径是:

  • →调用子类有参构造函数,并把该参数传值给父类有参构造函数
  • →调用父类有参构造函数,并给父类公共属性Name赋值
  • →子类实例调用父类的公共属性

其实,以上的做法在分层架构设计中已经得到了很好的使用。在分层架构中,通常会为所有的Repository创建一个基类,在基类中设计一个代表当前Repository的属性,并在基类的构造函数中为该属性赋值;最终,在创建子类Repository实例时,在为基类的、代表当前Repository的公共属性赋值。
在子类中,当父类通过base拿到子类的参数时,还可以对该参数做一些处理,比如代表父类的base把从子类拿到的参数转换成大写。

public class Student : Person
{
    public Student()
    {
      Console.WriteLine("我是学生");
    }
    public Student(string name)
      : base(ConvertToUpper(name))
    {
      Console.WriteLine("我是学生,我的名字叫{0}", name);
    }
    private static string ConvertToUpper(string name)
    {
      return name.ToUpper();
    }
}

输出结果:

我是人,我的名字叫DARREN
我是学生,我的名字叫darren
子类获取父类的Name属性值为DARREN

总结:
①.通过子类无参构造函数创建子类实例,会默认调用父类的无参构造函数
②.通过子类有参构造函数创建子类实例,也会默认调用父类的无参构造函数
③.在子类构造函数中通过base关键字指明父类构造函数,当通过子类构造函数创建实例,会调用指明的、父类的构造函数
④.父类的公共属性可以通过子类来赋值,子类也可以获取到父类的公共属性

### C# 中子父类之间的型转换 #### 子父类的转换 在 C# 中,子可以安全地转换为父类。这种转换被称为向上转型 (upcasting),因为子具有更具体的特性而父类更为通用。当执行此转换时,子特有的成员不会丢失,只是无法通过父类引用直接访问这些成员。 ```csharp class Animal { } class Dog : Animal { public void Bark() {} } Dog dog = new Dog(); Animal animal = dog; // 向上转型, 安全无误 ``` 此操作的意义在于提高代码灵活性和可重用性[^1]。例如,在集合中存储不同型的对象变得更容易管理,只需将它们视为共同基的对象即可。 #### 父类到子的转换 相反方向上的转换——即从父类向子转换,则需要显式的强制转换,并且只有当实际创建的是子实例时才有效。这称为向下转型(downcasting)。如果不满足条件尝试这样的转换将会抛出 `InvalidCastException` 异常。 ```csharp Animal someAnimal = GetSomeAnimal(); // 假设返回了一个 Dog 实例 if(someAnimal is Dog){ Dog myDog = (Dog)someAnimal; myDog.Bark(); // 只有确认是狗的情况下才能调用特定方法 } else{ Console.WriteLine("Not a dog"); } ``` 为了确保安全性并避免异常发生,通常建议先使用 `is` 或者模式匹配来验证型再做转换[^2]。 #### 继承层次结构中的接口实现 值得注意的是,虽然子不是直接继承其父类所遵循的所有接口,但是它确实继承了那些由父类具体实现方法。这意味着即使是一个间接派生自某个接口链末端的也可以被当作实现了那个接口来看待[^3]。 #### 使用场景举例 考虑一个简单的例子:有一个表示几何形状的基础抽象 Shape 和几个具体的派生 Circle、Rectangle 等。我们可以定义一个函数接收任意数量的各种形状作为输入参数: ```csharp void DrawShapes(List<Shape> shapes) { foreach(var shape in shapes){ shape.Draw(); } } ``` 在这个案例里,无论传入的具体是什么样的图形(圆形还是矩形),都可以统一处理,体现了面向对象编程的强大之处以及良好的设计实践[^4]。 #### 构造器初始化过程中的上下文传递 另外值得一提的是,在构造过程中可以通过 `base()` 关键字让子调用父类构造器的同时传递必要的数据给后者进行预处理或设置默认值等操作[^5]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值