【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("喵喵喵");
    }
}

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

归纳总结

  • **基类:**可实例化,有自己的变量、属性、方法,完整的独立功能。子类可复用其功能,对子类无强约束。只在功能继承时选择使用。
  • **抽象类:**不可实例化,有自己的变量、属性、方法,完整的独立功能。子类可复用其功能,对子类有强制方法约定,在子类中实现约定方法。在需要功能继承,且需要强制约定子类接口时选择使用。
  • **接口:**不可实例化,只做接口约定,无变量和方法实现。子类无复用功能,强制约定子类的方法,在子类中实现约定方法。在无需功能继承,需强制约定子类接口时选择使用。
相关推荐
李慕婉学姐2 小时前
【开题答辩过程】以《基于PHP的动漫社区的设计与实现》为例,不知道这个选题怎么做的,不知道这个选题怎么开题答辩的可以进来看看
开发语言·mysql·php
Lv11770082 小时前
Visual Studio 中的密封类和静态类
ide·笔记·c#·visual studio
魔芋红茶2 小时前
Netty 简易指南
java·开发语言·netty
武藤一雄2 小时前
[奇淫巧技] WPF篇 (长期更新)
windows·microsoft·c#·.net·wpf
洵有兮2 小时前
python第四次作业
开发语言·python
wjs20242 小时前
C++ 多线程编程入门指南
开发语言
小严家2 小时前
Java基础教程大全完整学习路径
java·开发语言·学习
毕设源码-朱学姐3 小时前
【开题答辩全过程】以 基于Java的电影推荐系统为例,包含答辩的问题和答案
java·开发语言
sheji34163 小时前
【开题答辩全过程】以 基于SSM的校园新冠疫苗接种信息管理系统为例,包含答辩的问题和答案
java·开发语言