重新认识抽象类和接口的区别

简介: 因为平时项目中用到的很少,这种基础的问题,看了忘,忘了看。从网上找到的千篇一律。今天自己试验一下这些说法。      三、抽象类和接口的区别:      1.类是对对象的抽象,可以把抽象类理解为把类当作对象,抽象成的类叫做抽象类.而接口只是一个行为的规范或规定,微软的自定义接口总是后带able字段,证明其是表述一类类“我能做。

因为平时项目中用到的很少,这种基础的问题,看了忘,忘了看。从网上找到的千篇一律。今天自己试验一下这些说法。

     三、抽象类和接口的区别:
      1.类是对对象的抽象,可以把抽象类理解为把类当作对象,抽象成的类叫做抽象类.而接口只是一个行为的规范或规定,微软的自定义接口总是后带able字段,证明其是表述一类类“我能做。。。”.抽象类更多的是定义在一系列紧密相关的类间,而接口大多数是关系疏松但都实现某一功能的类中.
      2.接口基本上不具备继承的任何具体特点,它仅仅承诺了能够调用的方法;     
      3.一个类一次可以实现若干个接口,但是只能扩展一个父类
      4.接口可以用于支持回调,而继承并不具备这个特点.
      5.抽象类不能被密封。
      6.抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的,当然您也可以声明为虚的.
      7.(接口)与非抽象类类似,抽象类也必须为在该类的基类列表中列出的接口的所有成员提供它自己的实现。但是,允许抽象类将接口方法映射到抽象方法上。   
       8.抽象类实现了oop中的一个原则,把可变的与不可变的分离。抽象类和接口就是定义为不可变的,而把可变的座位子类去实现。
      9.好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。如果一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其他方法,就叫接口污染。
     10.尽量避免使用继承来实现组建功能,而是使用黑箱复用,即对象组合。因为继承的层次增多,造成最直接的后果就是当你调用这个类群中某一类,就必须把他们全部加载到栈中!后果可想而知.(结合堆栈原理理解)。同时,有心的朋友可以留意到微软在构建一个类时,很多时候用到了对象组合的方法。比如asp.net中,Page类,有Server Request等属性,但其实他们都是某个类的对象。使用Page类的这个对象来调用另外的类的方法和属性,这个是非常基本的一个设计原则。
    11.如果抽象类实现接口,则可以把接口中方法映射到抽象类中作为抽象方法而不必实现,而在抽象类的子类中实现接口中方法.

 

第一条:简单点说就是抽象类是对类的抽象,接口是一个行为的规范,其他的就太XX了看不懂。

第二条:可以理解为继承接口只是为了使用接口中的方法

第三条:类可以继承自多个接口,只能继承一个类,接口也可以继承自多个接口啊,区别就是接口能不能继承自类了,写一个接口让他继承一个类。

     interface  Interface1 : Class1
    {
    }

 

程序报错:

在写一个抽象类让他继承接口和类是不会报错的。

 第四条:意思就是接口可以支持回调,但是抽象类不支持回调。总网上找了个例子来试试。

img_405b18b4b6584ae338e0f6ecaf736533.gif 代码
     public   class  CallBackDemo
    {
        
public   static   void  CallBackFunction()
        {
            
// 传递对象给接口类型变量(IBack)
            Controller obj  =   new  Controller( new  CallBack());
            
// 调用对象方法
            obj.Start();
        }
    }

    public interface IBack
    {
        void Run();
    }
    public class CallBack : IBack
    {

        #region IBack Members

        public void Run()
        {
            Console.WriteLine(DateTime.Now);
        }

        #endregion
    }


    
public   class  Controller
    {
        
public  IBack CallBackObj  =   null ;
        
public  Controller(IBack obj)
        {
            CallBackObj 
=  obj;
        }

        
public   void  Start()
        {
            Console.WriteLine(
" 敲击键盘任意键显示当前时间,直到按Esc退出 " );
            
while (Console.ReadKey( true ).Key  !=  ConsoleKey.Escape)
            {
                CallBackObj.Run();
            }
        }
    }

 

这个例子很简单的,就是只要不按下ESC键,他就一直执行输出当前时间,Controller类的构造函数的参数是一个接口类型的,当给他传入一个他的实现类的对象就会调用这个对象的方法输出当前时间。

结果如下:

然后用抽象类来代替这个接口看看能不能实现这个功能:

img_405b18b4b6584ae338e0f6ecaf736533.gif 代码
 1       public   class  CallBackDemo
 2      {
 3           public   static   void  CallBackFunction()
 4          {
 5               // 传递对象给接口类型变量(IBack)
 6              Controller obj  =   new  Controller( new  CallBack());
 7               // 调用对象方法
 8              obj.Start();
 9          }
10      }
11       // public interface IBack
12       // {
13       //     void Run();
14       // }
15       // public class CallBack : IBack
16       // {
17 
18       //     #region IBack Members
19 
20       //     public void Run()
21       //     {
22       //         Console.WriteLine(DateTime.Now);
23       //     }
24 
25       //     #endregion
26       // }
27       public   abstract   class  IBack
28      {
29           public   abstract   void  Run();
30      }
31       public   class  CallBack : IBack
32      {
33           public   override   void  Run()
34          {
35              Console.WriteLine(DateTime.Now);
36          }
37      }
38       public   class  Controller
39      {
40           public  IBack CallBackObj  =   null ;
41           public  Controller(IBack obj)
42          {
43              CallBackObj  =  obj;
44          }
45 
46           public   void  Start()
47          {
48              Console.WriteLine( " 敲击键盘任意键显示当前时间,直到按Esc退出 " );
49               while (Console.ReadKey( true ).Key  !=  ConsoleKey.Escape)
50              {
51                  CallBackObj.Run();
52              }
53          }
54      }

 

现在让Controller的构造方法接受一个IBack类型的变量,一样可以实现的。这条区别有点牵强。

第五条:抽象类不能被密封,意思就是说抽象类不能被密封,接口可以被密封。密封之后就不能被继承了,所以只要用出现:来继承就会报错。应该也会出现这样的错误的,接口也不能被密封。这条也说不过去。

写一个语句:

public sealed abstract class IBack{} 报错

意思很明显了就是说IBack这个抽象类不能被密封或是静态的。

吧sealed用在接口上public sealed interface IBack{}报错:

意思是关键字sealed不可以用在接口上,这里用item这个词,也就是说接口相当于一个变量。

两种都会报错啊,这条区别也有点牵强啊。

第六条:抽象类实现的具体方法默认为虚的,但实现接口的类中的接口方法却默认为非虚的。

抽象类中的方法是虚拟的,但是不提供virtual关键字来修饰,如果写上了会报错,接口中的方法是公共的不能申明为虚拟的。这条很明显。代码如下:

1       public    interface  IBack
2      {
3           virtual   void  Run();
4      }

 

报错如下:

将抽象类中的方法表示为虚拟的也会报错。

     public   abstract   class  IBack
    {
        
public   virtual   abstract   void  Run();
    }
同样也会报错: 有了abstract关键字就不需要再申明为virtual的了,看来抽象和虚拟是有些类似的,抽象函数也是虚拟的。
第七条:第一句不是他两个的区别,是共同点,第二句和第十一条说的一个意思,可以让接口实现抽象类,但是不实现抽象类中的方法,但是这种做法很怪异,估计项目中不会用到这样的。
 

 

 第八条:抽象类实现了oop中的一个原则,把可变的与不可变的分离。抽象类和接口就是定义为不可变的,而把可变的座位子类去实现。这条说的也是相同点嘛,不是区别。

第九条:好的接口定义应该是具有专一功能性的,而不是多功能的,否则造成接口污染。如果一个类只是实现了这个接口的中一个功能,而不得不去实现接口中的其他方法,就叫接口污染。更谈不上区别了。

第十条:尽量避免使用继承来实现组建功能,而是使用黑箱复用,即对象组合。因为继承的层次增多,造成最直接的后果就是当你调用这个类群中某一类,就必须把他们全部加载到栈中!后果可想而知.(结合堆栈原理理解)。同时,有心的朋友可以留意到微软在构建一个类时,很多时候用到了对象组合的方法。比如asp.net中,Page类,有Server Request等属性,但其实他们都是某个类的对象。使用Page类的这个对象来调用另外的类的方法和属性,这个是非常基本的一个设计原则。说的是使用组合对象避免多重继承,这也不是区别啊。

第十一条:和第七条的后半句雷同的,抽象类可以实现接口,但是不是具体实现,而是在他的子类中实现。这也不是区别。

 

对于接口和抽象类的区别,哪位大侠能够给点经典的,经得起推敲的答案啊,还有什么时候要用抽象类?什么时候要用接口?

作者:Tyler Ning
出处:http://www.cnblogs.com/tylerdonet/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过以下邮箱地址williamningdong@gmail.com  联系我,非常感谢。

目录
相关文章
|
6月前
|
Serverless PHP
当谈论面向对象编程时,这四个概念是非常重要的。以下是对接口、继承、封装和多态的简要说明
本文介绍了面向对象编程的四个核心概念:接口、继承、封装和多态。接口定义对象的行为规范,类通过实现接口确保符合所需行为。继承允许在已有类基础上创建新类,实现代码重用。封装是将数据和操作捆绑并隐藏内部细节,提高安全性和可维护性。多态使对象在运行时能表现出不同行为,增加代码灵活性和可扩展性。文中还提供了代码示例来说明这些概念。
38 0
|
6月前
|
Java
Java面向对象程序设计5接口与抽象类
Java面向对象程序设计5接口与抽象类
63 0
|
6月前
|
Java 数据安全/隐私保护 开发者
从零到一:深入理解Java中的封装、继承与多态
从零到一:深入理解Java中的封装、继承与多态
471 0
|
6月前
|
存储 Java
【面试问题】接口和抽象类有什么区别?
【1月更文挑战第27天】【面试问题】接口和抽象类有什么区别?
系统认知Java接口、接口与继承、接口与多态
在面向对象的基础之上,接口的出现是类性质的一种完善,是继承机制的一种补充,是体现多态性的一种形式。从生活实际出发,接口把它之下一系列复杂的逻辑,功能等通过“实现接口”的方式封装简化出来,只通过连接一个小小的口子就轻而易举地实现了背后实则很复杂的功能。我想这就是接口存在的意义所在吧。
209 0
系统认知Java接口、接口与继承、接口与多态
|
Java
抽象类和接口的区别(通俗易理解)
抽象类和接口的区别(通俗易理解)
516 0
|
C# 索引
走进C# abstract,了解抽象类与接口的异同
走进C# abstract,了解抽象类与接口的异同
108 0
|
Java 容器
Java面向对象接口
Java面向对象接口
120 0
|
设计模式 Java 编译器
一文彻底搞懂抽象类和接口!
一文彻底搞懂抽象类和接口!
128 0
|
设计模式 Java
快速分清抽象类与接口 | 带你学《Java面向对象编程》之六十一
本节结合实际情景,直观地为读者列表展示了抽象类与接口在不同维度上的区别。
快速分清抽象类与接口   | 带你学《Java面向对象编程》之六十一
下一篇
无影云桌面