抽象类及接口详解

1、前言

  在上一节中咱们讲到抽象类和接口之间的异同,咱们一块儿回顾下其异同。html

  同:c#

  一、都不能够被实例化ide

  二、都含有声明但未实现的方法学习

  三、均可以被继承spa

  四、其子类必须实现其声明未实现的方法设计

  异:code

  一、接口是多继承,抽象类是单继承(一个类仅能继承一个抽象类,但能够继承多个接口)htm

  二、抽象类能够包含实现的方法,接口不能包含实现的方法对象

  三、接口支持回调,抽象类不支持blog

  四、抽象类更多的定义在一些类关系紧密的类间,接口则定义在实现其某一种功能之间

  抽象类和接口的异同咱们再次熟悉了一遍,今天咱们主要讲的是抽象类和接口使用场景及详讲抽象类的使用方法及接口的使用方法

2、使用场景

  抽象类、普通类、接口。咱们到底何时使用哪个呢?这就很头痛了,不是一直使用一个就是好的。每个都有每个的使用场景。下面咱们看看到底啥事时候用啥东西吧。

  咱们如今假设一个场景,如今须要设计一个程序,用来描述各个动物的一些生活习性,这里咱们就有猪、猫、狗。

  不使用抽象类也不使用接口。咱们设计他们三个的各个习性,就是猪的类里面就包含本身的习性,猫类里面包含本身的习性,狗类里面包含本身的习性。若是各个习性较多但也有相同的。这样的类看起来很是的冗余。

  咱们加入抽象类(设计实现大的功能单元),定义一个抽象类-哺乳动物类,其中定义了共同的习性,走路的方法,呼吸的方法,繁衍下一代的方法。可是叫声不同。咱们又声明一个叫声的方法不实现(抽象方法)。这样再咱们去定义猪类或者狗类的时候只须要写出不同的地方便可。这样看起来代码也简洁,清楚

  咱们如今改用接口(设计实现小而简练的功能),咱们把这些动物能够作什么列出来,而后统一使用接口去定义公共的。好比叫声,行走。这些功能,咱们就可使用接口来定义声明。而后继承再去实现。

到了这里,咱们总结下到底咱们编写程序为何须要使用抽象类呢?为何须要使用接口呢?单一用一个普通的类很差吗?简单又容易。其实否则。存在即合理。咱们一块儿看看到底为何要使用吧

  为何使用抽象类?

  抽象类每每用来表征对问题领域进行分析、设计中得出的抽象概念,是对一系列看上去不一样,可是本质上相同的具体概念的抽象`。这样来讲若是一个类设计就是为了给其余类继承的,它表明一类对象所具备的公共属性或方法,咱们就使用抽象类。就像上门的这个例子,把一些动物共同的属性或者方法提取出来,定义一个抽象类。代码变的易懂,代码冗余减小,变得简洁明了。实现了代码复用性。

  那么为何使用接口呢?

  通俗点讲就是为了下降代码的耦合度。接口的意义在于抽象,不拘细节,从而使同类事物在在同一高度具备通用性及可替代性。上面的例子来说,规定好了这个叫声这个方法,那么继承的就去实现这个叫声方法就行了。若是某天加入了一个新的动物,这样咱们也不须要修改其余的任何方面,仅继承一下接口修改自己便可,不须要修改或改变其余的类或者接口。系统的灵活性增长了。

 

  这里可能会有个问题了。既然有了抽象类为何还要用接口呢?这会不会有点多余?

  答案确定是不会的。那么有了抽象类为何还要使用接口呢?咱们看看抽象类和接口的异同就很快能明白了。

  一、接口提供的事统一的行为规范,供其余调用,而抽象类具备接口的特性同时还能够有本身的具体实现

  二、抽象类只能有一个父类,能够实现多个接口

 

  那么咱们如何使用抽象类和接口呢?

3、抽象类及接口使用

  就拿咱们上面举的那个例子来编写一段代码:

    /// <summary>
    /// 叫声的接口定义
    /// </summary>
    public interface ICry
    {
        string Cry();
    }

    /// <summary>
    /// 说话的接口定义
    /// </summary>
    public interface ISay
    {
        string Say();
    }

 
    /// <summary>
    /// 动物抽象的抽象类
    /// </summary>
    public abstract class Animale
    {
        /// <summary>
        /// 包含的实现了的方法、呼吸、走路
        /// </summary>
        /// <returns></returns>
        public static string Breathe()
        {
            return "呼吸同样";
        }

        public static string Run()
        {
            return "走路同样";
        }

        /// <summary>
        /// 未实现的抽象方法睡觉方法
        /// </summary>
        /// <returns></returns>
        public abstract  string Sleep();
    }

    
    /// <summary>
    /// 普通的类  继承了抽象类及两个接口
    /// </summary>
    public class Dog: Animale,ICry, ISay
    {
        /// <summary>
        /// 实现重写抽象方法睡觉
        /// </summary>
        /// <returns></returns>
        public override  string Sleep() { return "睡觉"; }

       /// <summary>
       /// 实现叫声接口方法
       /// </summary>
       /// <returns></returns>
        public  string Cry() { return "旺旺"; }

        /// <summary>
        /// 实现说话接口方法
        /// </summary>
        /// <returns></returns>
        public string Say() { return "说话"; }

    }

 

  在上面的代码中,咱们列举出了接口的定义及抽象类、抽象方法的定义及使用。在最下面一个普通类中,咱们继承了一个抽象类及两个接口,能够实现多个接口可是只能有一个抽象父类。若是继承两个抽象类的话会报错的。

  抽象类关键字--abstract

  接口关键字--interface

 

4、扩展延伸(密封类)

  讲到抽象类,咱们也能够一块儿看看密封类,密封类不能做为基类,禁止派生。若是重写了某些功能会致使编译错误或者为了防止第三方进行扩展重写,这个时候咱们就可使用到密封类。

  重点注意

    一、密封类中不能包含虚方法(Virtual)和抽象方法(abstract)。由于密封类是不能被继承的也就没有派生类,就不具有实现抽象方法和虚方法的机会。

    二、在使用密封类(sealed)的时候,密封类将限制它的使用,如今及将来都将受到影响

    三、若是实例方法包含了sealed修饰符,那么它也必须包含override修饰符,其父类方法必须包含virtual修饰符

     /// <summary>
    /// 普通动物类
    /// </summary>
    public  class Animals
    {
        /// <summary>
        /// 动物的叫声方法,由于其派生类重写了次方法,因此必须使用virtual修饰符
        /// </summary>
        /// <returns></returns>
        public virtual  string Cry() {
            return "叫声";
        }
    }

    /// <summary>
    /// 动物狗类密封类,没法产生派生类,不能做为基类,继承了动物类
    /// </summary>
    public sealed class Dog : Animals
    {
        /// <summary>
        /// 重写了动物叫的方法,同时标记为了密封方法
        /// </summary>
        /// <returns></returns>
        public  override  sealed   string Cry()
        {
            return "旺旺";
        }
    }

  在使用密封类的时候咱们须要考虑的因素须要更加的全面,更加的谨慎,以防后面从新推翻重写。每一个东西都没有绝对的好,只有你用的恰到好处。多思考多选择才是智者。

总结

                    c#基础知识详解系列

欢迎你们扫描下方二维码,和我一块儿学习更多的C#知识

相关文章
相关标签/搜索