C# 子类、接口

栏目总目录


子类

继承的概念

  • 继承机制:C#支持单继承,即一个类只能直接继承自一个基类。但基类本身可以继承自另一个类,从而实现继承链。
  • 继承关键字 :使用冒号(:)表示继承关系,子类在声明时指定其基类。

子类的成员

  • 继承的成员:子类会继承基类的非私有成员(public、protected、internal、protected internal)。私有成员(private)不会被继承。
  • 新增的成员:子类可以定义自己的新成员,这些成员与继承自基类的成员共存。
  • 重写的成员 :子类可以使用override关键字重写继承自基类的虚方法(virtual methods)或抽象方法(abstract methods)。重写允许子类为继承的方法提供特定的实现。

访问修饰符与继承

  • 访问修饰符:基类和子类成员的访问级别会影响它们的可访问性和继承性。例如,私有成员在子类中不可见,而受保护的成员(protected)在派生类中可见但在外部不可见。
  • 内部(internal)与受保护内部(protected internal):这两种访问修饰符在继承时具有特定的作用域。internal成员在同一程序集中可见,而protected internal成员在同一程序集及其派生类中可见。

构造函数与析构函数

  • 构造函数:子类在实例化时会首先调用基类的构造函数(如果有的话)。如果基类有无参构造函数,则子类的无参构造函数会隐式调用它。如果基类只有带参数的构造函数,则子类必须显式调用基类的构造函数,通常是在子类构造函数的初始化列表中完成。
  • 析构函数:子类析构函数会先执行子类的清理代码,然后自动调用基类的析构函数(如果存在)。

抽象类与密封类

  • 抽象类:抽象类不能被实例化,但可以作为其他类的基类。抽象类可以包含抽象方法(只有声明没有实现的方法),这些方法必须在非抽象派生类中被重写。
  • 密封类 :密封类(使用sealed关键字修饰)不能被其他类继承。这有助于防止类被不恰当地扩展。

接口实现

  • 接口实现:虽然子类直接继承自基类,但子类也可以实现接口。接口实现与类继承不同,接口定义了一组方法、属性等成员的规范,而不提供实现。实现接口的类必须为接口中的每个成员提供具体实现。

示例

csharp 复制代码
using System;

public class Animal
{
    public void Eat()
    {
        Console.WriteLine("This animal eats food.");
    }
}

public class Dog : Animal
{
    public override void Eat()
    {
        Console.WriteLine("Dog eats meat.");
    }

    public void Bark()
    {
        Console.WriteLine("Dog barks.");
    }
}

class Program
{
    static void Main(string[] args)
    {
        Dog myDog = new Dog();
        myDog.Eat(); // 输出: Dog eats meat.
        myDog.Bark(); // 输出: Dog barks.
    }
}

在这个示例中,Dog类继承自Animal类,并重写了Eat方法。此外,Dog类还定义了自己的Bark方法。在Main方法中,我们创建了Dog类的一个实例,并调用了它的EatBark方法。


接口

接口定义

  • 基本定义 :接口是一种引用类型,使用interface关键字声明。它指定了一组方法、属性、事件和索引器的规范,但不提供这些方法的具体实现。
  • 命名约定 :按照惯例,接口名称通常以大写字母"I"开头,后跟接口名称的其余部分,如IExampleInterface
  • 成员定义:接口中的成员只有声明,没有实现。成员声明使用分号结束,而不是大括号。
  • 访问修饰符 :接口成员默认为public,且不允许使用privateprotected修饰符。

接口特性

  • 不能直接实例化:接口本身不能被实例化,因为它不包含实现。只有实现了接口的类或结构才能被实例化。
  • 抽象成员:接口中的所有成员都是抽象的,即它们不包含实现代码。
  • 多继承:接口支持多继承,一个接口可以继承自一个或多个其他接口。
  • 隐式与显式实现:类可以实现接口,并通过隐式或显式方式提供接口成员的实现。隐式实现允许通过类实例直接访问接口成员,而显式实现则要求通过接口实例来访问。

用途

  • 定义契约:接口定义了一组规范,实现接口的类必须遵循这些规范。这有助于确保不同类之间的互操作性。
  • 解耦:通过接口,可以实现类之间的解耦,即类的实现细节对彼此是透明的。这有助于降低系统的复杂性和提高可维护性。
  • 多态性:接口是实现多态性的重要手段之一。通过接口引用,可以指向实现了该接口的任何类实例,从而允许在运行时动态地替换对象的行为。
  • 依赖注入:在依赖注入等设计模式中,接口被广泛用于定义服务的契约,以便在不修改代码的情况下替换服务的实现。

实现

  • 实现接口的类:只有类和结构(在C#中)才能实现接口。实现接口的类必须提供接口中声明的所有成员的实现。
  • 实现语法 :在类定义中,通过冒号(:)后跟接口名称来指定该类实现的接口。如果类实现了多个接口,接口名称之间用逗号分隔。
  • 接口继承:当类实现了某个接口时,它也可以继承该接口继承的所有其他接口的成员。这意味着实现接口的类必须提供所有这些接口成员的实现。

与类的比较

  • 继承关系:类只能单继承(即只能继承自一个基类),但接口支持多继承。
  • 实现与继承:类继承不仅是说明继承(即继承基类的声明),也是实现继承(即继承基类的实现)。而接口继承只是说明继承,即派生接口继承了父接口的成员声明,但没有继承实现。
  • 成员类型:接口只能包含方法、属性、事件和索引器的声明,不能包含字段、常量、运算符、实例构造函数、析构函数或静态成员。类则可以包含所有这些类型的成员。

示例

csharp 复制代码
public interface IExampleInterface
{
    void Method1();
    int Property1 { get; set; }
}

public class ExampleClass : IExampleInterface
{
    public void Method1()
    {
        Console.WriteLine("Method1 implementation");
    }

    public int Property1 { get; set; }
}

在这个示例中,IExampleInterface接口定义了一个无返回值的方法Method1和一个读写属性Property1ExampleClass类实现了这个接口,并提供了Method1方法和Property1属性的具体实现。

相关推荐
Ajiang282473530428 分钟前
对于C++中stack和queue的认识以及priority_queue的模拟实现
开发语言·c++
幽兰的天空32 分钟前
Python 中的模式匹配:深入了解 match 语句
开发语言·python
Theodore_10223 小时前
4 设计模式原则之接口隔离原则
java·开发语言·设计模式·java-ee·接口隔离原则·javaee
----云烟----5 小时前
QT中QString类的各种使用
开发语言·qt
lsx2024066 小时前
SQL SELECT 语句:基础与进阶应用
开发语言
开心工作室_kaic6 小时前
ssm161基于web的资源共享平台的共享与开发+jsp(论文+源码)_kaic
java·开发语言·前端
向宇it6 小时前
【unity小技巧】unity 什么是反射?反射的作用?反射的使用场景?反射的缺点?常用的反射操作?反射常见示例
开发语言·游戏·unity·c#·游戏引擎
武子康6 小时前
Java-06 深入浅出 MyBatis - 一对一模型 SqlMapConfig 与 Mapper 详细讲解测试
java·开发语言·数据仓库·sql·mybatis·springboot·springcloud
九鼎科技-Leo6 小时前
什么是 WPF 中的依赖属性?有什么作用?
windows·c#·.net·wpf
转世成为计算机大神7 小时前
易考八股文之Java中的设计模式?
java·开发语言·设计模式