抽象类和接口

最近空暇的时光多多,突然发现自己很多上学时学的基础知识在工作中不是常用的情况下变得渐渐模糊,好可怕,今天先从基础开始,从新认识一下抽象类,接口。个人理解,不喜勿喷哦。

抽象类:abstract

在面向对象的概念中,所有的对象都是通过类来描绘的,但是反过来,并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类。简单说,具有抽象行为的类,就是抽象类。要区别一点:抽象类可以没有抽象方法,但有抽象方法的一定是抽象类。

简单的抽象类:

    ///
    /// 定义抽象类
    ///
    abstract public class Animal
    {
        //构造方法
        public Animal()
        {
            Console.WriteLine("Animal()");
        }
        //定义静态字段
        static protected int _id;
        //定义属性
        public abstract static int Id//在抽象方法声明中不能使用 static 或 virtual 修饰符
        {
            get;
            set;
        }
        //定义方法
        public abstract void Eat();
        //定义索引器
        public string this[int i]
        {
            get;//必须声明主体,因为它未标记为 abstract、extern 或 partial

            set;
        }
        //定义非抽象静态方法
    }


可知,抽象类可以包含成员变量,非静态抽象构造方法,非静态抽象方法,索引器,普通方法等。抽象类无法创建实例的,但是可以通过创建一个抽象类类型的变量,使用子类的实例对它进行初始化。Animal an = new Dog();

public abstract static int Id        {
            get;
            set;
        }

会编译报错: 静态成员“Animal.Id”不能标记为 override、virtual 或 abstract 原因是抽象类不可以包含静态抽象构造方法和静态抽象方法

实现抽象类:

继承抽象类并且实现其所有抽象方法,否则,子类也是抽象类。子类实现抽象类的抽象方法是通过Override该抽象方法得到的。顺带提一下Override和Overload的差别,Override是对方法体的重写,而Overload是对方法签名(方法的返回值和参数)进行的重载。

    ///
    /// 实现抽象类
    ///
    public class Dog : Animal
    {
        public static override int Id
        {
            get { return _id; }
            set { _id = value; }
        }
        public override void Eat()
        {
            Console.Write("Dog Eats.");
        }
    }

编译一下会有错误提示,有兴趣的朋友可以去自己修改一下练练手。

接口:interface

在设计软件时,可以定义的发现软件(或单模块)需要的外部函数。但是这些函数无法由本软件设计者实现。无法由本软件设计者实现的原因很复杂,多种多样。或者是因为这些函数用于采集数据,而数据与真实的业务相关。或者是由于软件在要包括windows,mac,linux,os20等多个操作系统上实现,甚至在一个还未出现但有可能出现的平台上实现,那么只能将这些函数交给其他人实现。这些已经准确定义了功能、输入、输出的函数就被称为接口。

1. 接口是一个引用类型,通过接口可以实现多重继承。
2. C#中接口有new、public、protected、internal、private等修饰符。
3. 接口中只能声明抽象成员(所以不能直接对接口进行实例化(即不能使用new操作符声明一个接口的实例对 象)),而不能声明共有的域或者私有的成员变量。
4. 接口声明不包括数据成员,常量、域、构造函数、析构函数、静态成员,只能包含方法、属性、事件、索引等成员。
5. 接口名称一般都以“I”作为首字母(当然不这样声明也可以),这也是接口和类的一个区别之一。
6. 接口成员的访问级别是默认的(默认为public),所以在声明时不能再为接口成员指定除public外的任何访问修饰符,否则 编译器会报错。
7. 接口成员不能有static、abstract、override、virtual修饰符,使用new修饰符不会报错,但会给出警告说不需要关键字new。
8. 在声明接口成员的时候,不准为接口成员编写具体的可执行代码,也就是说,只要在对接口进行声明时指明接口的成员名称和参数就可以了。
9. 接口一旦被继承,子类需要把接口中所有成员实例化(通过具体的可执行代码实现接口抽象成员的操作)。

接口的声明

interface ISampleInterface
    {
        void SampleMethod();
    }

接口的实现,只需实现接口中方法的方法体。

class ImplementationClass : ISampleInterface
    {
        // Explicit interface member implementation:
        void ISampleInterface.SampleMethod()
        {
            // Method implementation.
        }
    }

可以通过“,”来分隔实现的多个接口,从而实现多继承,例如

class ImplementationClass : ISampleInterface1, ISampleInterface2


共同点

1.都具有抽象行为,抽象类是部分具有,接口是完全。

2.抽象类和接口都不能直接实例化,如果要实例化,抽象类变量必须指向实现所有抽象方法的子类对象,接口变量必须指向实现所有接口方法的类对象。

3.抽象类要被子类继承,接口要被类实现。即他们的抽象行为要被赋予实际行为。

差别

1.接口只能做方法申明,抽象类中可以做方法申明,也可以做方法实现

2.接口只能包含方法、属性、事件、索引等成员,不包括数据成员,常量、域、构造函数、析构函数、静态成员。抽象类就是一个特殊的类,具有一般类的行为特征。

3.接口里定义的变量只能是公共的静态的常量即声明为public static final,抽象类中的变量是普通变量。

4.抽象类里的抽象方法必须全部被子类所实现,如果子类不能全部实现父类抽象方法,那么该子类只能是抽象类。同样,一个实现接口的时候,如不能全部实现接口方法,那么该类也只能为抽象类。

5.接口可继承接口,并可多继承接口,但类只能单根继承。

想到的差不多就这些,可能会有遗漏,希望大家可以提出来。

原文地址:https://www.cnblogs.com/Mushrooms/p/3569049.html