接口和抽象类的定义和使用

原文网址:https://www.cnblogs.com/fangyz/p/5259619.html

其他相关内容网址:https://www.cnblogs.com/ben-zhang/archive/2012/12/18/2823455.html

https://blog.csdn.net/softwareldu/article/details/44948775

接口和抽象类的区别:https://www.cnblogs.com/binyao/p/4891306.html

接口和抽象类:https://www.cnblogs.com/goalie/p/9460400.html

1.接口的特点

  接口的定义是指定一组函数成员而不实现成员的引用类型,其它类型和接口可以继承接口。定义还是很好理解的,但是没有反映特点,接口主要有以下特点:

(1)通过接口可以实现多重继承,C#接口的成员不能有public、protected、internal、private等修饰符。原因很简单,接口里面的方法都需要由外面接口实现去实现方法体,那么其修饰符必然是public。C#接口中的成员默认是public的,java中是可以加public的。

(2)接口成员不能有new、static、abstract、override、virtual修饰符。有一点要注意,当一个接口实现一个接口,这2个接口中有相同的方法时,可用new关键字隐藏父接口中的方法。

(3)接口中只包含成员的签名,接口没有构造函数,所有不能直接使用new对接口进行实例化。接口中只能包含方法、属性、事件和索引的组合。接口一旦被实现,实现类必须实现接口中的所有成员,除非实现类本身是抽象类。

(4)C#是单继承,接口是解决C#里面类可以同时继承多个基类的问题。

2.接口的简单使用

 

 class Program
    {
        static void Main(string[] args)
        {
            IWorker james1 = new James1();
            IWorker james2 = new James2();
            james1.work("设计");
            james2.work("编程");
            //从这个例子我体会到了有接口的好处,可以想象如果又来了新的员工。
            //如果不采用接口,而是每个员工都有一个单独的类,这样就会容易出错。
            //如果有接口这种协议约束的话,那么只要实现了接口就肯定有接口里声明的方法,我们只需拿来调用。
        }
    }
    public interface IWorker{ void work(string s); }
    class James1 : IWorker
    {
        public void work(string s)
        {
            Console.WriteLine("我的名字是James1,我的工作是" +s);
        }
    }
    class James2 : IWorker
    {
        public void work(string s)
        {
            Console.WriteLine("我的名字是James2,我的工作是"+s);
        }
    }

3.一个可以实例化接口的特例

    class Program
    {
        static void Main(string[] args)
        {
            //C#中COM接口是可以实例化的,但其实这种写法是使接口“映射”到某一个类上,实际上创建的是这个类的实例。
            IWorker worker = new IWorker();
        }
    }
    [ComImport, CoClass(typeof(James1))]
    [Guid("d60908eb-fd5a-4d3c-9392-8646fcd1edce")]
    public interface IWorker{ void work(string s); }
    //ComImport特性发生在tlbimp.exe导入COM类型类库的时候,生成的托管类型会标记有ComImport特性
    //Guid特性是一个GUID标识,COM类型是用GUID来标识的。

 

利用.NET Reflector查看时可以很明显的看到Main方法里面的代码是:IWorker worker=new James1();

 4.接口和抽象类的区别

接口用于规范,抽象类用于共性。抽象类是类,所以只能被单继承,但是接口却可以一次实现多个。
接口中只能声明方法,属性,事件,索引器。而抽象类中可以有方法的实现,也可以定义非静态的类变量。
抽象类可以提供某些方法的部分实现,接口不可以。抽象类的实例是它的子类给出的。接口的实例是实现接口的类给出的。
在抽象类中加入一个方法,那么它的子类就同时有了这个方法。而在接口中加入新的方法,那么实现它的类就要重新编写(这就是为什么说接口是一个类的规范了)。
接口成员被定义为公共的,但抽象类的成员也可以是私有的、受保护的、内部的或受保护的内部成员(其中受保护的内部成员只能在应用程序的代码或派生类中访问)。此外接口不能包含字段、构造函数、析构函数、静态成员或常量。

  还有一点,我们在VS中实现接口时会发现有2个选项,一个是实现接口,一个是显示实现接口。实现接口就是我们平常理解的实现接口,而显示实现接口的话,实现的方法是属于接口的,而不是属于实现类的。

抽象类


  抽象方法是没有代码实现的方法,使用abstract关键字修饰;

  1. 抽象类是包含0到多个抽象方法的类,其不能实例化。含有抽象方法的类必须是抽象类,抽象类中也可以包含非抽象方法;
  2. 重写抽象类的方法用override关键字。

 

 1 //定义一个抽象类,包含一个抽象方法,但该方法未实现
 2 abstract class MyAbs{
 3     public abstract void AbMethod();            
 4 }
 5 //定义一个非抽象派生类,只能继承一个类
 6 class MyClass:MyAbs{
 7      public override void AbMethod(){
 8         Console.WriteLine("此MyClass中实现父类中未实现的抽象方法!");
 9      }
10  }
11 //在主程序中实例化一个MyClass对象,并调用AbMethod方法
12 static void Main(string[] args){
13     MyClass objMyClass = new MyClass();
14     objMyClass.AbMethod();
15 }

 

 

  • 虚方法(virtual)与抽象方法(abstract)的区别
  1. 虚方法必须要有方法体,抽象方法不允许有方法体;
  2. 虚方法可以被子类(派生类)重载(override),抽象方法必须被子类重载;
  3. 虚方法除了在密封类中都可以写,抽象方法只能在抽象类中写。

 

接口


  接口是一套规范,遵守这个规范就可以实现功能。

  1. 接口中只定义方法的原型,不能有字段和常量;
  2. 继承接口的类必须实现接口中所有的方法才能实例化

 

1 //隐式声明为public
2 public interface IPict{
3     //只有方法声明,没有访问修饰符,没有实现
4     int DeleteImage();
5     void DisplayImage();
6 }

 

  定义派生自接口的类,并实现所有接口中的方法

 

 1 public class MyImages: IPict{
 2     //第一个方法的实现
 3     public int DeleteImage(){
 4         Console.WriteLine("DeleteImage实现!");
 5     }
 6     
 7     //第二个方法的实现
 8     public void DisplayImage(){
 9         Console.WriteLine("DisplayImage实现!");
10     }
11 }

  在主程序中实例化一个MyImages对象,并调用DeleteImage和DisplayImage方法

 

1 static void Main(string[] args){
2     MyImages ofjM = new MyImages();
3     objM.DisplayImage();
4     int t = objM.DeleteImage();
5     Console.WriteLine(t);
6 }

 

 

  • 多重接口实现

  C#不允许多重类继承,但允许多重接口实现。但如果发生命名冲突就需要使用前缀进行显式接口实现或调用。如果继承接口的类中用显示方法实现接口中的方法时,实现方法不需加访问修饰符(public)

 1 public interface IPict{
 2     void DisplayImage();
 3 }
 4 
 5 public interface IPictManip{
 6     void DisplayImage();
 7 }
 8 
 9 public class MyImages: IPict, IPictManip{
10     void IPict.DisplayImage(){    //如果用显示接口实现方法,则不需使用访问修饰符
11         Console.WriteLine("DisplayImage的IPict实现");
12     }
13     void IPictManip.DisplayImage(){
14         Console.WriteLine("DisplayImage的IPictManip实现");
15     }
16 }
17 
18 static void Main(string[] args){
19     MyImages objM = new MyImages();
20     IPict Pict = objM;    //IPict引用
21     Pict.DisplayImage();
22     IPictManip PictManip = objM;  //IPictManip引用
23     PictManip.DisplayImage();
24 }

 

 

  • 使用自定义接口

  接口作为参数使用:接口作为参数传递了实现接口的对象

 

1 //无论谁收作业参数类型部分都不需做任何改变
2 private void DoCollectHomework(IHomeworkCollector collector){
3     collector.CollectHomework();
4 }
5 
6 DoCollectHomework(scofield);

 

  接口作为返回值使用:接口作为返回值返回了一个实现接口的对象

 

 1 private IHomeworkColletor CreateHomeworkCollector(string type){
 2     switch(type){
 3         case "student":
 4         collector = new Student("Scofield", Genders.Male, 28, "越狱");
 5         break;
 6     }
 7     //返回一个实现该接口的对象
 8     return collector
 9 }
10 
11 collector.CollectHomework();
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值