`
卒子99
  • 浏览: 75388 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

接口,抽象类的使用

阅读更多
   以前在使用接口的时候,就知道它可以抽象系统模型,便于扩展。但到底什么时候使用接口,什么时候使用抽象类,我一直也不是很清楚。但最新做了一个项目,其中遇到抽象一个系统模型的时候,让我明白了他们的用途。废话少说,直接上Case了
  需求:从文件中系统中读取数据,可支持从TXT文件,XML,XLS.....

  这个是最初的需求,很简单,系统支持从多文件格式读取数据,首先抽象出一个AbstractFileDataParser类,类图如下:
AbstractFileDataParser类代码如下:
public abstract class AbstractFileDataParser
{
    private FileInputStream fileInputStream = null;

    public AbstractFileDataParser(FileInputStream fileInputStream)
    {
        if (fileInputStream == null)
        {
            throw new NullPointerException("file input stream is null!");
        }
        this.fileInputStream = fileInputStream;
    }

    protected FileInputStream getFileInputStream()
    {
        return this.fileInputStream;
    }

    public void release()
    {
        CloseUtil.close(fileInputStream);
    }

}

   最主要的方法就是readData,类似于BufferedReader,每次调用读取一组数据,如果还回Null,表示数据读取完成了。
   如果从项目的需要上来看,这个抽象应该是满足需求了。但现在有考虑问题,会老想着抽象,所以又想了到了一个新的抽象层:只是读取数据。这就意味着不知道什么地方获取数据,文件系统,网络等,于是需要进一步抽象,这个时候就需要定义一个IDataParser接口,类图抽象层次如下所示
IDataParser接口代码如下:

public interface IDataParser
{
    /**
     * 
     * 如果还回null,则代表没有可读取的数据了 
     * 
     * @return
     */
    Object[] readData();

    void release();

}

AbstractFileDataParser类实现IDatParser接口,代码如下:
public abstract class AbstractFileDataParser implements IDataParser
{
    private FileInputStream fileInputStream = null;

    public AbstractFileDataParser(FileInputStream fileInputStream)
    {
        if (fileInputStream == null)
        {
            throw new NullPointerException("file input stream is null!");
        }
        this.fileInputStream = fileInputStream;
    }

    protected FileInputStream getFileInputStream()
    {
        return this.fileInputStream;
    }

    public void release()
    {
        CloseUtil.close(fileInputStream);
    }
}


   这个抽象层次就比较清楚了,虽然暂时项目中只是从文件中读取数据,但并不保证以后可能会改变啊,抽象出一个接口,就很好满足了OCP。而AbstractFileDataParser类作为项目实际需求,可以实现文件读入流的获取和关闭,实现了一些共同行为。
   我想这就是接口和抽象类的最大区别了吧
  • 描述: AbstractFileDataParser
  • 大小: 1.9 KB
  • 描述: 抽象层次
  • 大小: 3 KB
分享到:
评论
33 楼 puroc 2008-11-21  
我的做法是,如果一个类就能实现功能的话,绝对不为其定义一个抽象类或者接口。如果以后有需求的话,在增加也来得及。如果是有多个实现的话,那么我一般定义为接口,如果这多个实现类有可以复用的方法时,就把这些提到一个抽象类中,让这个抽象类实现接口,然后所有的实现类继承这个抽象类。
32 楼 puroc 2008-11-21  
grandboy 写道
思想有时不太好表达。有的时候就是那种“只可以意会,不可言传”的感觉。还是就lz的代码谈, 如果我没有理解错的话,楼主的那个接口真是有点多余。其实只要一个抽象类里面再定义一个抽象方法就行了。不能为了接口而接口。代码如下:
public abstract class AbstractFileDataParser 
{  
    private FileInputStream fileInputStream = null;  
  
    public AbstractFileDataParser(FileInputStream fileInputStream)  
    {  
        if (fileInputStream == null)  
        {  
            throw new NullPointerException("file input stream is null!");  
        }  
        this.fileInputStream = fileInputStream;  
    }  
  
    protected FileInputStream getFileInputStream()  
    {  
        return this.fileInputStream;  
    }  
  
    public void release()  
    {  
        CloseUtil.close(fileInputStream);  
    }  
    
    abstract Object[] readData();  
}


然后在子类里就可以实现这个readData()方法。



同意不能为了接口而接口的说法。像兄台这样,把这个方法定义为抽象方法。然后用实现类去实现他,没有问题。但如果现在还有另外一个抽象类B,也定义了一个抽象方法,而刚才那个实现类,也需要实现抽象类B的抽象方法。应该就没办法写了,除非让这个抽象类B继承你的抽象类,这样实现类才可以实现这两个抽象方法。但如果把你的抽象类和抽象类B修改为借口,那么这两个接口之间不需要有任何关系,实现类就可以同时实现他们的抽象方法了。
31 楼 mooniscrazy 2008-11-18  
接口对外,抽象类对内。
接口是战略层面的,抽象类是战术层面的。
抽象类的出现,只是为了省几行代码,没有它也是无所谓的。
抽象类,一般只有少数几个类使用它。而且,有可能存在几个不同的抽象类。
抽象类不能当作接口使用。
之所以会在这个问题上有疑惑,说明对创建型模式理解不正确。
仔细想想如何创建这个抽象类,想想如何屏蔽抽象类的实现细节,然后在想想出现几个抽象类的情况,想明白了就不会暴露抽象类了。
抽象类的正确用法,就是在包内部使用。应该是default访问修饰符。或者是更小的protected,不应该是public。
30 楼 sea7 2008-11-17  
williamy 写道
1,抽象類就是爲了extends的
2,interface是爲了多態的
如果你看過多繼承,那麽你就明白interface是多餘的,
interface害死人啊,java莫名其妙的來個interface
就是爲了讓那些沒看過c++的人明白怎麽實現多繼承
並且,其實還是一個假的多繼承


晕...

接口实现的是一种契约的关系,而抽象类实现的才是继承的关系.
29 楼 cjjer 2008-10-20  
接口一般对的事外面扩展和快速引用。关心的是事情本身的实现方法或者一个路径而已。
抽象类一般可以做两件事情,内部的松耦合;逻辑实现。关心的是具体的实现。
28 楼 xixix2004 2008-10-15  
看了楼上的帖子真的想说大家都是地道的程序员。

可是接口的引用并不源于编程,而是现实生活中的设计。针对编码中的接口和抽象类谁好谁坏进行争论是毫无意义的。同理也包括针对接口的使用是否有必要这样的争论。

之前楼上有人说“接口是针对外部使用者,而抽象类是针对内部”这样的观点就很精辟了。想想看为什么你家插座上的插孔都是二头三头,而内部线路的排放却千差万别就知道了。因为插座是提供给外部使用的。

面向接口的编程确实听起来很时髦,但是先想想有没有必要,是不是一定要用接口。一些规模小的公司的程序员会说,完全没必要,我们不用接口做出来的项目一样过硬,一些大公司的程序员会说,接口是必须的。

这是为什么?不是他们的项目差别有多大,而且就算不用接口也不会影响运行效率。而是因为,大公司里人员比较多,在多人共同开发一个项目的时候,他们需要设计一个或者若干个接口来作为一个标准,才不至于使项目的开发显得混乱。

也就是说接口的使用与否在代码层面完全无关紧要。

虽然这样说有人会觉得我藐视接口的作用,呵呵,经历过就会知道了。
27 楼 gnomewarlock 2008-10-14  
world123 写道
public class Cellphone extends Phone implements Bluetooth{  
}

这个比喻比较牛逼
26 楼 world123 2008-09-18  
public class Cellphone extends Phone implements Bluetooth{  
}
25 楼 czlonly 2008-09-17  
我感觉抽象类就是一类具有共性的对象的抽象表现,抽象类的方法表现了共同的动作与行为,而接口所描述的动作或行为,只是用了一个形象的描述名称,其具体内容要视实现它的类来决定
24 楼 ddppfamily 2008-09-17  
看了楼主的帖子,突然感觉大脑好~~~~清醒。
23 楼 liqiaoyuan 2008-09-16  
如果一个类已经继承别的类!它还能继承抽象类么?这时只能使用接口,其实接口就是一个特殊的抽象类。我觉得在实际开发中,尽量少使用抽象类。不知道我说的对不对,如果不对请大家给点建议。
22 楼 grandboy 2008-09-14  
思想有时不太好表达。有的时候就是那种“只可以意会,不可言传”的感觉。还是就lz的代码谈, 如果我没有理解错的话,楼主的那个接口真是有点多余。其实只要一个抽象类里面再定义一个抽象方法就行了。不能为了接口而接口。代码如下:
public abstract class AbstractFileDataParser 
{  
    private FileInputStream fileInputStream = null;  
  
    public AbstractFileDataParser(FileInputStream fileInputStream)  
    {  
        if (fileInputStream == null)  
        {  
            throw new NullPointerException("file input stream is null!");  
        }  
        this.fileInputStream = fileInputStream;  
    }  
  
    protected FileInputStream getFileInputStream()  
    {  
        return this.fileInputStream;  
    }  
  
    public void release()  
    {  
        CloseUtil.close(fileInputStream);  
    }  
    
    abstract Object[] readData();  
}


然后在子类里就可以实现这个readData()方法。
21 楼 HRoger 2008-09-09  
我觉得用继承是为了达到复用,用接口是为了达到灵活(松耦合),权衡二者的利弊之后再决定
20 楼 bonny 2008-07-24  
接口做名词
抽象类做动词

框架主要是抽象类+工厂。
19 楼 allaneiaaa 2008-07-24  
一般会分离实现的。不会abstract class AbstractFileDataParser implements IDataParser。而是采用注入的方式。比较好。 典型的策略或者模板设计模式。
18 楼 taowen 2008-06-30  
楼主需要的接口可以简化为
Iterable<YourDataType>
17 楼 zfyyfz 2008-05-05  
我觉得抽象内和继承相关,比如拿文档类来说,都有title,time属性,并且getTime,setTime都是相同方法,就用抽象类处理;
接口运用比较广泛,大多为了解耦,使高层完全不用知道子类的变换和约定的一个协约,这样高层就不再依赖底层。灵活调用,当底层发生变化时也完全不用通知高层。
16 楼 WorldHello 2008-04-29  
从面向对象分析与设计的角度来说:
abstract class表示“is-a”的关系,即父类与继承类本质上一致的;
对于interface,并不要求interface的实现者和interface定义在概念本质上是一致的, 只表示一种契约关系,可以将interface看成“like-a”或者“has-a”的关系(这种说法不是很准确)。

举例来说:电视机、收音机同属电器,具有打开,关闭,调台的方法;同时电视机、收音机都有遥控器(收音机带遥控器的好像不多!)。

类结构如下:
abstract class 电器{
       public void 打开(){}
       public void 关闭(){}
       public void 调台(){}
}

interface 遥控器{
      void 遥控(){}
}

class  电视机 extends 电器 implements 遥控器{
       //重写方法,略
}
class  收音机 extends 电器 implements 遥控器{
       //重写方法,略
}
15 楼 Ab.Yann 2008-04-29  
同意楼上所说的:interface关注的是外部的使用者,而Abstract Class是对内的。

接口是定义了一些规格(规则),这些规格是对外的.
抽象类则是对内部变化的一种封装.
14 楼 joachimz 2008-04-19  
williamy 写道
1,抽象類就是爲了extends的
2,interface是爲了多態的
如果你看過多繼承,那麽你就明白interface是多餘的,
interface害死人啊,java莫名其妙的來個interface
就是爲了讓那些沒看過c++的人明白怎麽實現多繼承
並且,其實還是一個假的多繼承


忍不住要晒一下观点:interface是约定的contract,对外部调用者的承诺,设计精髓的体现(对象的职责)。良好的interfacer设计可以保证边界清晰、程序的稳定、真正的松耦合。
而Abstract Class是对内部实现的一个基础,最多只是对内部实现提供一些重用而已。或者说,interface关注的是外部的使用者,而Abstract Class是对内的。
并且在复杂的环境下,继承会带来许多副作用。继承层次多,或者扩展点过多时,增加一个子类绝对是一个灾难:需要了解大量父类的内部实现细节,例如经典的Template Method、Strategy等模式。组合应该是更好的实现方式。

我的理解,面向对象更重要的是,保持整体结构的清晰、模块的松耦合。而不是小范围的重用问题。Procedure/Function的重用也可以很好,甚至更简单、容易。

相关推荐

    详细解析Java中抽象类和接口的区别

    - **抽象类**:继承抽象类使用`extends`关键字。 - **接口**:实现接口使用`implements`关键字。 这反映了两者在概念上的不同定位:抽象类强调的是“是什么”的关系(例如,狗是动物的一种),而接口强调的是“能做...

    接口与抽象类区别

    接口与抽象类区别 在软件开发中,接口和抽象类是两个常用的概念,但它们之间的区别却让许多人感到困惑。那么,什么是抽象类和接口?它们之间有什么区别?下面,我们就来详细地探讨这个问题。 一、抽象类 抽象类是...

    接口和抽象类使用详细实例源代码

    在编程世界中,接口(Interface)和抽象类(Abstract Class)是面向对象设计的...通过阅读和分析“接口和抽象类使用详细实例源代码”,开发者可以更好地掌握这两种重要概念,并将其应用到自己的项目中,提升软件质量。

    java 抽象类与接口的练习

    在Java编程语言中,抽象类和接口是两种重要的面向对象设计概念,它们允许我们定义规范,供其他类去实现或继承。在这个练习中,我们将深入理解这两种机制,并通过实际的代码示例和注释来加深理解。 首先,让我们讨论...

    C#抽象类与接口方法

    【C#抽象类与接口方法】在C#编程语言中,抽象类和接口是两种用于实现多态性和封装的关键概念,它们允许我们设计灵活、可扩展的代码结构。 抽象类是一种特殊的类,它不能被实例化,而是作为其他类的基类使用。抽象类...

    Java 接口和抽象类

    在 Java 中,抽象类使用 abstract 关键字声明。 在上面的练习中,我们使用抽象类来编写 Java 程序。首先,我们创建了一个名为 LivingThing 的抽象类,该类表示生物类。然后,我们创建了两个具体实现类:Human 和 ...

    Java抽象类与接口实验报告

    Java抽象类与接口实验报告

    C#类、接口、虚方法和抽象方法-抽象类和接口的相同点和区别

    在C#编程语言中,类、接口、虚...在选择使用抽象类还是接口时,应根据项目需求和设计原则来权衡。例如,如果需要共享部分实现并有继承关系,可以选择抽象类;如果需要多个类实现一组共同行为,接口可能是更好的选择。

    java利用接口和抽象类改写求圆的面积和梯形的面积.docx

    在了解了接口和抽象类的定义和使用格式之后,我们可以根据以下几点来选择使用接口还是抽象类: 1. **成员实现详情**:抽象类可以提供成员的实现详情,而接口不能。如果你希望在抽象类中提供某些方法的默认实现,则...

    接口抽象类

    本文将深入探讨“接口抽象类”的主题,包括它们的概念、用途、区别以及在Java编程语言中的实现。 首先,让我们了解什么是接口。接口在Java中是一种完全抽象的类型,它只包含方法签名(方法名、返回类型和参数列表)...

    java抽象类与接口实例java抽象类与接口实例

    java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例java抽象类与接口实例...

    java中接口与抽象类的详细分析与比较

    在Java编程语言中,接口(Interface)和抽象类(Abstract Class)都是用于实现多态性的关键概念,它们各自有特定的用途和优缺点。本文将深入探讨这两种概念,帮助你理解它们之间的区别以及如何在实际开发中选择使用...

    c# 中抽象类和接口的学习

    在实际开发中,选择使用抽象类还是接口取决于你的具体需求。如果你需要共享一些通用的实现逻辑,或者需要强制派生类遵循某种结构,那么抽象类可能是更好的选择。相反,如果你的目标是提供一组操作的契约,让多个类...

    C#接口抽象类区别实例

    c#中抽象类和接口。 相同点: (1) 都可以被继承 (2) 都不能被实例化 (3) 都可以包含方法声明 (4) 派生类必须实现未实现的方法 区 别: (1) 抽象基类可以定义字段、属性、方法实现。接口只能定义属性、索引器、事件、...

    Java继承_抽象类与接口的应用.

    1.继承及继承实例 2.方法重写(Overwrite) 3.super关键字 4.方法重载(Overload) 5.final修饰符 6.abstract修饰符 7.抽象类 8.接口 9.接口和抽象类对比 10.接口和抽象类使用场合实例 11.总结

    抽象类和接口实验报告.doc

    抽象类和接口实验报告

    java 抽象类与接口的区别

    例如,在设计模式中,工厂模式通常使用抽象类,而策略模式则倾向于使用接口。 理解抽象类与接口的区别并恰当运用,有助于提升代码的可扩展性和可维护性,使得软件设计更加灵活和面向对象。在进行Java编程时,应根据...

    Java语言的接口与抽象类

    在选择使用抽象类还是接口时,需要根据实际需求权衡。如果需要共享代码和方法,或者希望强制子类实现特定行为,抽象类是合适的选择。如果希望解耦系统,提供更灵活的扩展性,或者保护实现的细节,接口是更好的选择。

    Java实验7抽象类和接口.pdf

    抽象类和接口 ...通过这个实验,我们学习了抽象类、接口、Cloneable 接口和多态性的概念,并掌握了如何使用它们来编写 Java 程序。我们还学习了浅拷贝和深拷贝的概念,并掌握了如何消除浅拷贝的方法。

    抽象类和接口

    在编程领域,抽象类和接口是面向对象设计中的两个重要概念,它们用于实现代码的抽象和多态性。本实验旨在帮助你深入理解和熟练运用这两种机制。 首先,让我们来看看抽象类。抽象类是一种不能被实例化的类,它通常...

Global site tag (gtag.js) - Google Analytics