论坛首页 Java企业应用论坛

接口,抽象类的使用

浏览 19352 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (6)
作者 正文
   发表时间:2008-02-24  
   以前在使用接口的时候,就知道它可以抽象系统模型,便于扩展。但到底什么时候使用接口,什么时候使用抽象类,我一直也不是很清楚。但最新做了一个项目,其中遇到抽象一个系统模型的时候,让我明白了他们的用途。废话少说,直接上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
   发表时间:2008-04-04  
楼主写的有些不是很明确,能在完善一些嘛?既然实现了IDataParser 接口,为什么没有接口实现?
0 请登录后投票
   发表时间:2008-04-04  
卒子99 写道
   以前在使用接口的时候,就知道它可以抽象系统模型,便于扩展。但到底什么时候使用接口,什么时候使用抽象类,我一直也不是很清楚。但最新做了一个项目,其中遇到抽象一个系统模型的时候,让我明白了他们的用途。废话少说,直接上Case了
  需求:从文件中系统中读取数据,可支持从TXT文件,XML,XLS.....

 
   这个抽象层次就比较清楚了,虽然暂时项目中只是从文件中读取数据,但并不保证以后可能会改变啊,抽象出一个接口,就很好满足了OCP。而AbstractFileDataParser类作为项目实际需求,可以实现文件读入流的获取和关闭,实现了一些共同行为。
   我想这就是接口和抽象类的最大区别了吧



我看了一下楼主的想法,

我的感觉可能和楼主不太一致!

从多种源中读数据,这个肯定是多个实现,不用说了,
如果我来设计,
如果只是读,只有一段代码的话,那就用接口好了,不为别的,干净!

如果是读了之后,还有一段都相同的处理代码,

那就使用抽象类好了。

写两个方法,

abstract String readXML()
{
}

void dealString()
{

String aa = this.readXML();
处理aa;
}

这样不是显得更好样一点???
0 请登录后投票
   发表时间:2008-04-04  
用抽象类,来实现这种中间多层的实现,

23GOF里,叫模板的模式!


有现成的用别人的成果吧,这样比较省事!
0 请登录后投票
   发表时间:2008-04-04  
确实是模板模式
所谓模板模式就是把一系列类中相同的部分抽取出来形成抽象,不同的方法不同实现!
0 请登录后投票
   发表时间:2008-04-15  
dearmite 写道
卒子99 写道
   以前在使用接口的时候,就知道它可以抽象系统模型,便于扩展。但到底什么时候使用接口,什么时候使用抽象类,我一直也不是很清楚。但最新做了一个项目,其中遇到抽象一个系统模型的时候,让我明白了他们的用途。废话少说,直接上Case了
  需求:从文件中系统中读取数据,可支持从TXT文件,XML,XLS.....

 
   这个抽象层次就比较清楚了,虽然暂时项目中只是从文件中读取数据,但并不保证以后可能会改变啊,抽象出一个接口,就很好满足了OCP。而AbstractFileDataParser类作为项目实际需求,可以实现文件读入流的获取和关闭,实现了一些共同行为。
   我想这就是接口和抽象类的最大区别了吧



我看了一下楼主的想法,

我的感觉可能和楼主不太一致!

从多种源中读数据,这个肯定是多个实现,不用说了,
如果我来设计,
如果只是读,只有一段代码的话,那就用接口好了,不为别的,干净!

如果是读了之后,还有一段都相同的处理代码,

那就使用抽象类好了。

写两个方法,

abstract String readXML()
{
}

void dealString()
{

String aa = this.readXML();
处理aa;
}

这样不是显得更好样一点???



确实,接口越简单越好,甚至可以只是一个标识接口
但是在实际运用中可以发现,对于这种动名词命令的接口(自己定义的),非常有必须留一个方法用于清除资源,就像Connection, Reader这样的
0 请登录后投票
   发表时间:2008-04-15  
是不是我的意思没有表述清楚呢?
大家都在讨论这个到底是什么模式,
其实我只是想表述什么时候选择用接口,什么时候选择用抽象类
0 请登录后投票
   发表时间:2008-04-15  
1,抽象類就是爲了extends的
2,interface是爲了多態的
如果你看過多繼承,那麽你就明白interface是多餘的,
interface害死人啊,java莫名其妙的來個interface
就是爲了讓那些沒看過c++的人明白怎麽實現多繼承
並且,其實還是一個假的多繼承
0 请登录后投票
   发表时间:2008-04-16  

[quote="williamy"]2,interface是爲了多態的
如果你看過多繼承,那麽你就明白interface是多餘的,
interface害死人啊,java莫名其妙的來個interface
就是爲了讓那些沒看過c++的人明白怎麽實現多繼承
並且,其實還是一個假的多繼承[/quote]


interface就是用来实现多态的,和继承有关系吗?

例如,如果有一个基类叫做Person,现在我需要它具有一个父亲的特性,采用继承有关系,就如下

 public class Father extend Person

{
.........
public void readStoryToBaby(){}
}

 

又出现一个老板类,又会产生以下继续关系

 public class Father extend Person

{
public void meeting(){}
}


 

 

 

 

 

 最后事业有成了,又是孩子的父亲,又是老板,那怎么做呢?我不懂C++,大概可能是这样子的

 public class SuccessMan extend Father,Boss

{
pulbic void readStoryToBaby(){}
public void meeting(){}
}

 

这就会有一个问题了,在公司环境中,你的雇员可以让我们的Boss讲故事,而在家里,你的孩子可能会让你给他讲故事。在系统中是没有必要,也不应该讲其它方法暴露出来的。
而使用接口是很好的做到这点的

 public class SuccessMan implements Father,Boss

{
pulbic void readStoryToBaby(){}
public void meeting(){}
}

 

在工作环境中:

 public class WorkContext 

{
public WorkdContext(Boss boss){}
}

 

而在家里:

public class Home

{
public Home(Father father){}
}

 

这样不是会更优雅些吗?

0 请登录后投票
   发表时间:2008-04-16  
public class Cellphone extends Phone implements Bluetooth{
}
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics