【C#】关于接口和抽象类的一些知识点与比较

目录

关于接口:

接口的说明

接口的声明方法

接口的一个实现:

接口的继承

关于抽象类:

抽象类的定义和特征:

使用抽象类:

抽象类之间的继承关系:

抽象类、接口、类三者的继承:


——————————————————————————————————————————————————

18.11.27首次编辑

————————————————————————————————————————————————————

接口和抽象类是面向对象中最重要的两个概念,两者的作用相似,都是同一类型和规范派生类的属性和方法。

关于接口:

接口的说明

  • 接口是一种程序的约定,本身并不去实现成员的方法,而是通过派生类来实现。接口可以使得程序更加清晰,更加具有条理【主要作用】
  • 实际上,接口只是一种约定,定义了该接口有哪些方法,但是并未对这些方法具体的实现。
  • 接口定义了语法合同 "是什么" 部分,派生类定义了语法合同 "怎么做" 部分,接口内的方法在派生类中必须全部实现。
  • 接口定义了属性、方法和事件,这些都是接口的成员。接口只包含了成员的声明。成员的定义是派生类的责任。接口提供了派生类应遵循的标准结构。
  • 接口使得实现接口的类或结构在形式上保持一致。

    抽象类在某种程度上与接口类似,但是,它们大多只是用在当只有少数方法由基类声明由派生类实现时。

接口的声明方法

例如:这段代码定义了接口 IMyInterface。通常接口命令以 I 字母开头,这个接口只有一个方法 MethodToImplement(),没有参数和返回值,当然我们可以按照需求设置参数和返回值。

//接口使用 interface 关键字声明,它与类的声明类似。接口声明默认是 public 的。下面是一个接口声明的实例:
interface IMyInterface    
{
    void MethodToImplement();
}

//接口一般定义格式如下所示。
[attributes] [modifiers] interface identifier [:base-list] {interface-body}[;]
attributes(可选): 属性,一般省略,目前没遇到实例
modifiers(可选):修饰符,即public,注意显性和隐性的区别:https://www.cnblogs.com/summer1987/p/4600100.html
identifier:接口名称。
base-list(可选):
 interface-body:

接口需要注意的几点:

  1. 接口内的方法不能用public abstract等修饰。接口内不能有字段变量,构造函数。
  2. 接口内可以定义属性(有get和set的方法)。如string color { get ; set ; }这种。
  3. 实现接口时,必须和接口的格式一致。
  4. 必须实现接口的所有方法。
  5. 接口中只包含成员的签名,接口没有构造函数,所有不能直接使用 new 对接口进行实例化。接口中只能包含方法、属性、事件和索引的组合。接口一旦被实现,实现类必须实现接口中的所有成员,除非实现类本身是抽象类。
  6. C# 是单继承,接口是解决 C# 里面类可以同时继承多个基类的问题【解决多继承问题】,类不能继承两个基类。要实现多重继承的功能,就要利用类和接口之间的继承关系。类可以继承两个以上的接口,也可以在继承基类的同时,再继承另外一个接口。所以实现多重继承关系有两种方法:接口的多重继承【多个接口】和类的多重继承【单个基类+额外接口】。

接口的一个实现:

using System;
//1、接口常常以字母I开头
interface IMyInterface
{
    // 接口成员,可以在其中添加参数和返回值,但不能在接口中实现方法,仅仅作为“目录”的功能
    void MethodToImplement();
}
//一个类,来实现这个接口,语法上和继承很像
class A : IMyInterface
{
    static void Main()
    {
        //2、用类A来实例化一个对象,继承接口
        A iImp = new A();
        iImp.MethodToImplement();
    }
    //3、在这里对方法进行实现,方法名必须与接口定义的方法名一致。
    public void MethodToImplement()
    {
        //方法在这里实现
        Console.WriteLine("MethodToImplement() called.");
    }
}

 

关于实现接口的语法:很类似类的继承,通常I开头

class InterfaceImplementer : IMyInterface

 

接口的继承

如果是接口进行了继承(接口继承接口):

如果一个接口继承其他接口,那么实现类或结构就需要实现所有接口的成员

例:两个接口 IMyInterface 和 IParentInterface。

using System;
//父接口
interface IParentInterface
{
    void ParentInterfaceMethod();
}
//子接口,这里继承了父接口
interface IMyInterface : IParentInterface
{
    void MethodToImplement();
}
//类,实现了子接口
class InterfaceImplementer : IMyInterface
{
    static void Main()
    {
        //实例化一个类的对象,并分别调用两个接口的方法
        InterfaceImplementer iImp = new InterfaceImplementer();
        iImp.MethodToImplement();
        iImp.ParentInterfaceMethod();
    }
    //对子接口方法进行实现
    public void MethodToImplement()
    {
        Console.WriteLine("MethodToImplement() called.");
    }
    //对父接口方法进行实现
    public void ParentInterfaceMethod()
    {
        Console.WriteLine("ParentInterfaceMethod() called.");
    }
}

 

关于抽象类:

抽象类的作用和接口类似,同样也定义了一些为实现的方法。与接口不同的是,其中有一些方法已经实现了。所以,从概念上来讲,抽象类是介于接口和类之间的一种特殊的类。

抽象类的定义和特征:

  • 不能初始化的类被叫做抽象类,它们只提供部分实现,但是另一个类可以继承它并且能创建它们的实例,有未被实现的方法。抽象类不可以new对象

  • "一个包含一个或多个纯虚函数的类叫抽象类,抽象类不能被实例化,进一步一个抽象类只能通过接口和作为其它类的基类使用

有时候,类表达的并不是一个具体的事物,而是一个比较抽象的概念。所以,C#引入了一个新的概念,那就是抽象类。 抽象类使用abstract关键字定义,此关键字是放在类class关键字的前面,表示此类属于抽象类。例如定义一个抽象类Shape,就可以定义为如下的代码

abstract class Shape
{
    // 抽象类成员
}

抽象类的功能和接口类似,其中也定义了一些派生类必须要实现的方法。抽象类中的这些方法被称之为抽象方法,使用abstract关键字定义。如下面的代码就是在抽象类中定义了一个抽象方法。

abstract class Shape
{
    abstract public double GetArea();
}

在继承此抽象类的派生类中,必须要实现抽象方法GetArea()。在派生类中使用override关键字重写此抽象方法来实现。

抽象类中的抽象方法是通过派生类来实现的,而抽象类又可以继承接口,这样三者之间就形成了比较复杂的继承关系。在设计代码时,灵活利用三者的继承关系,可以使得“低耦合,高内聚”的特点体现得更加明显。

使用抽象类:

要求:
创建一个抽象类Shape,然后通过其派生类Rectangle实现其抽象方法GetArea()

namespace 抽象类test
{    
     //抽象类,作为基类来使用
    abstract class Shape
    {
        //注意抽象方法的定义也要加上abstract
        abstract public double GetArea(double a, double b);
    }

    class Rectangle : Shape
    {//注意这里继承了抽象类后,实现方法也要加上override的修饰词
        public override double GetArea(double a,double b)
        {return a * b;}
    }

    class Program
    {
        static void Main(string[] args)
        {
            Rectangle rectangle = new Rectangle();
            Console.WriteLine("面积:"+ rectangle.GetArea(20, 20));
            Console.ReadKey();
        }
    }
}

抽象类之间的继承关系:

不只是类可以继承抽象类,抽象类之间也可以存在继承关系。

代码改1:

要求:
在上一个练习要求下创建一个抽象类Graph,并继承了抽象类Shape,添加方法FillColor(),并在MAIN中调用

namespace 抽象类test
{
    abstract class Shape
    {
        abstract public double GetArea(double a, double b);
    }

    abstract class Graph:Shape
    {
        abstract public String FillColor(String a);
    }

    class Rectangle : Graph
    {
        public override string FillColor(String a)
        {return a;}
        public override double GetArea(double a,double b)
        {return a * b;}
    }

    class Program
    {
        static void Main(string[] args)
        {
            Rectangle rectangle = new Rectangle();
            Console.WriteLine("面积:"+ rectangle.GetArea(20, 20));
            Console.WriteLine("颜色为:"+rectangle.FillColor("绿色"));
            Console.ReadKey();
        }
    }
}

抽象类、接口、类三者的继承:

不只是抽象类之间,以及和类之间有继承关系,抽象类和接口之间同样可以有继承关系。

抽象类在继承接口时,可以实现接口定义的方法,也可以把该方法定义为抽象方法,而不去实现

实例:

namespace 抽象类test
{
    //新增接口,在接口中声明方法,这里不能直接实现该方法,而要通过派生类来实现
    interface IShape
    {
        double GetArea(double x, double y);
    }
    //抽象类1,继承了接口
    abstract class Shape:IShape
    {   //将接口中的方法抽象化,不实现
        abstract public double GetArea(double a, double b);
    }
    //抽象类2,继承了抽象类1
    abstract class Graph:Shape
    {
        abstract public String FillColor(String a);
    }
    //类1,继承了抽象类2,并在这里实现了最上边接口的方法
    class Rectangle : Graph
    {
        public override string FillColor(String a)
        {return a;}
        public override double GetArea(double a,double b)
        {return a * b;}
    }

    class Program
    {
        static void Main(string[] args)
        {
            Rectangle rectangle = new Rectangle();
            Console.WriteLine("面积:"+ rectangle.GetArea(20, 20));
            Console.WriteLine("颜色为:"+rectangle.FillColor("绿色"));
            Console.ReadKey();
        }
    }
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值