【C#知识点详解】基类、抽象类、接口类型变量与子类实例的归纳总结

今天来梳理一下基类、抽象类、接口不同类型变量和子类实例对象之间的关系。话不多说直接开始。

基本功能

  • 基类是具备完整功能的普通类,可直接创建实例。当基类有可复用的功能时,子类可直接继承,其主要作用是复用已有的变量、属性、方法。
  • 抽象类是不完整的模版类,不可以被直接创建实例。抽象类内部存在未被实现的抽象方法,子类继承抽象类后,需强制子类实现抽象方法。与普通类一样,抽象类同样存在可复用的变量、属性、方法。其主要作用是通过抽象方法约束子类结构,并同时拥有复用通用功能的能力。
  • 接口是纯方法定义,无任何功能的具体实现(C# 8.0 + 可加默认实现,但不推荐)。接口无法被实例化,需要继承后实现约定的方法。其主要作用是约定方法,并可以解除类的依赖关系,接口可以实现多重继承。

使用场景

基类、抽象类、接口都可以由子类继承,三者都可以由各自类型的引用变量持有子类实例。示例如下:

cs 复制代码
public class Program
{
    static void Main(string[] args)
    {
        BaseClass baseClass = new DerivedClass();
        AbstractClass abstractClass = new AbstractDerivedClass();
        Interface @interface = new InterfaceDerivedClass();

        Console.ReadKey();
    }
}

接下来就详细说明一下各自的区别和使用场景。

基类

基类是完整的普通了,封装了独立的变量、属性、方法。当子类继承基类时,可直接拥有基类的这些功能。示例如下:

cs 复制代码
public class Program
{
    static void Main(string[] args)
    {
        Animal dog = new Dog();
        dog.Call(); //输出:动物叫

        Animal cat = new Cat();
        cat.Call(); //输出:动物叫

        Console.ReadKey();
    }
}

public class Animal
{
    public void Call()
    {
        Console.WriteLine("动物叫");
    }
}

public class Dog : Animal
{
}

public class Cat : Animal
{
}

当基类方法标记为virtual时,子类可重写基类方法。虽然变量类型为基类(Animal),但创建出来的实例为子类(Dog、Cat),因此在方法的实际调用时,调用的是子类中重写的方法。示例代码如下:

cs 复制代码
public class Program
{
    static void Main(string[] args)
    {
        Animal dog = new Dog();
        dog.Call(); //输出:汪汪汪

        Animal cat = new Cat();
        cat.Call(); //输出:喵喵喵

        Console.ReadKey();
    }
}

public class Animal
{
    public virtual void Call()
    {
        Console.WriteLine("动物叫");
    }
}

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

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

通过上面的示例可以看出,可以通过基类类型统一的持有不同的子类类型,并调用子类中重写的方法,子类重写并非强制

通过这种特性,我们可以通过基类类型统一的管理不同的子类实例。如数组、方法参数等。示例如下:

cs 复制代码
public class Program
{
    static void Main(string[] args)
    {
        Animal[] animals = { new Dog(), new Cat() };
        for (int i=0;i<animals.Length;i++)
        {
            animals[i].Call();
        }

        Console.ReadKey();
    }
}

抽象类

抽象类在功能继承方面与基类相同,抽象类同样可以提供变量、属性、方法等完整的封装功能。抽象类的核心区别在于,可使用abstract 关键字标记抽象方法,抽象方法需在子类中强制实现,是一种强制性约定。由于抽象方法在基类未被实现,所以抽象类不能被实例化。

示例如下:

cs 复制代码
public class Program
{
    static void Main(string[] args)
    {
        Animal[] animals = { new Dog(), new Cat() };
        for (int i = 0; i < animals.Length; i++)
        {
            animals[i].Call();
        }

        Console.ReadKey();
    }
}

public abstract class Animal
{
    public abstract void Call();
}

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

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

抽象类同样可以用基类变量引用子类实例,即需要基类的功能继承,又需要与子类强制约定方法时,可采用抽象类。

接口

接口是纯方法定义,无任何功能实现。接口同样无法被实例化。接口的核心作用在于为不同的子类约定了接口,这些接口必须在子类中实现。示例如下:

cs 复制代码
public class Program
{
    static void Main(string[] args)
    {
        IAnimal[] animals = { new Dog(), new Cat() };
        for (int i = 0; i < animals.Length; i++)
        {
            animals[i].Call();
        }

        Console.ReadKey();
    }
}

public interface IAnimal
{
    public void Call();
}

public class Dog : IAnimal
{
    public void Call()
    {
        Console.WriteLine("汪汪汪");
    }
}

public class Cat : IAnimal
{
    public void Call()
    {
        Console.WriteLine("喵喵喵");
    }
}

与基类、抽象类相同,同样可以用接口类型变量引用子类实例,提供了统一的持有变量。不同在于接口类内部只能定义方法和属性,不能持有变量。

归纳总结

  • **基类:**可实例化,有自己的变量、属性、方法,完整的独立功能。子类可复用其功能,对子类无强约束。只在功能继承时选择使用。
  • **抽象类:**不可实例化,有自己的变量、属性、方法,完整的独立功能。子类可复用其功能,对子类有强制方法约定,在子类中实现约定方法。在需要功能继承,且需要强制约定子类接口时选择使用。
  • **接口:**不可实例化,只做接口约定,无变量和方法实现。子类无复用功能,强制约定子类的方法,在子类中实现约定方法。在无需功能继承,需强制约定子类接口时选择使用。
相关推荐
gjxDaniel2 小时前
Objective-C编程语言入门与常见问题
开发语言·objective-c
choke2332 小时前
[特殊字符] Python异常处理
开发语言·python
云中飞鸿2 小时前
linux中qt安装
开发语言·qt
少控科技2 小时前
QT第6个程序 - 网页内容摘取
开发语言·qt
darkb1rd2 小时前
八、PHP SAPI与运行环境差异
开发语言·网络安全·php·webshell
历程里程碑2 小时前
Linux20 : IO
linux·c语言·开发语言·数据结构·c++·算法
郝学胜-神的一滴2 小时前
深入浅出:使用Linux系统函数构建高性能TCP服务器
linux·服务器·开发语言·网络·c++·tcp/ip·程序人生
承渊政道2 小时前
Linux系统学习【Linux系统的进度条实现、版本控制器git和调试器gdb介绍】
linux·开发语言·笔记·git·学习·gitee
JQLvopkk3 小时前
C# 轻量级工业温湿度监控系统(含数据库与源码)
开发语言·数据库·c#
玄同7653 小时前
从 0 到 1:用 Python 开发 MCP 工具,让 AI 智能体拥有 “超能力”
开发语言·人工智能·python·agent·ai编程·mcp·trae