2008-02-24
接口,抽象类的使用
关键字: 接口 抽象类
以前在使用接口的时候,就知道它可以抽象系统模型,便于扩展。但到底什么时候使用接口,什么时候使用抽象类,我一直也不是很清楚。但最新做了一个项目,其中遇到抽象一个系统模型的时候,让我明白了他们的用途。废话少说,直接上Case了
需求:从文件中系统中读取数据,可支持从TXT文件,XML,XLS.....
这个是最初的需求,很简单,系统支持从多文件格式读取数据,首先抽象出一个AbstractFileDataParser类,类图如下:
AbstractFileDataParser类代码如下:
最主要的方法就是readData,类似于BufferedReader,每次调用读取一组数据,如果还回Null,表示数据读取完成了。
如果从项目的需要上来看,这个抽象应该是满足需求了。但现在有考虑问题,会老想着抽象,所以又想了到了一个新的抽象层:只是读取数据。这就意味着不知道什么地方获取数据,文件系统,网络等,于是需要进一步抽象,这个时候就需要定义一个IDataParser接口,类图抽象层次如下所示
IDataParser接口代码如下:
AbstractFileDataParser类实现IDatParser接口,代码如下:
这个抽象层次就比较清楚了,虽然暂时项目中只是从文件中读取数据,但并不保证以后可能会改变啊,抽象出一个接口,就很好满足了OCP。而AbstractFileDataParser类作为项目实际需求,可以实现文件读入流的获取和关闭,实现了一些共同行为。
我想这就是接口和抽象类的最大区别了吧
需求:从文件中系统中读取数据,可支持从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类作为项目实际需求,可以实现文件读入流的获取和关闭,实现了一些共同行为。
我想这就是接口和抽象类的最大区别了吧
评论
taowen
2008-06-30
楼主需要的接口可以简化为
Iterable<YourDataType>
Iterable<YourDataType>
hunter001201
2008-06-30
对于lz的设计
我建议 如果是 "多文件格式读取数据"行为,你可以设计成接口
如果是"多文件格式读取数据器",你可以设计成抽象类
我建议 如果是 "多文件格式读取数据"行为,你可以设计成接口
如果是"多文件格式读取数据器",你可以设计成抽象类
hunter001201
2008-06-30
抽象类与接口的关系,本质是类与接口的关系.
到底什么可以划分到类,什么需要借口? 你是怎么考虑的呢?
类是一些比较实在的,可以具体看到或感觉到的东西,各种水果,例如梨,苹果等.
接口指契约,规定.一般是描述一些动作行为. 比如飞翔,呼吸等.
到底什么可以划分到类,什么需要借口? 你是怎么考虑的呢?
类是一些比较实在的,可以具体看到或感觉到的东西,各种水果,例如梨,苹果等.
接口指契约,规定.一般是描述一些动作行为. 比如飞翔,呼吸等.
zfyyfz
2008-05-05
我觉得抽象内和继承相关,比如拿文档类来说,都有title,time属性,并且getTime,setTime都是相同方法,就用抽象类处理;
接口运用比较广泛,大多为了解耦,使高层完全不用知道子类的变换和约定的一个协约,这样高层就不再依赖底层。灵活调用,当底层发生变化时也完全不用通知高层。
接口运用比较广泛,大多为了解耦,使高层完全不用知道子类的变换和约定的一个协约,这样高层就不再依赖底层。灵活调用,当底层发生变化时也完全不用通知高层。
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 遥控器{
//重写方法,略
}
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 遥控器{
//重写方法,略
}
Ab.Yann
2008-04-29
同意楼上所说的:interface关注的是外部的使用者,而Abstract Class是对内的。
接口是定义了一些规格(规则),这些规格是对外的.
抽象类则是对内部变化的一种封装.
接口是定义了一些规格(规则),这些规格是对外的.
抽象类则是对内部变化的一种封装.
joachimz
2008-04-19
williamy 写道
1,抽象類就是爲了extends的
2,interface是爲了多態的
如果你看過多繼承,那麽你就明白interface是多餘的,
interface害死人啊,java莫名其妙的來個interface
就是爲了讓那些沒看過c++的人明白怎麽實現多繼承
並且,其實還是一個假的多繼承
2,interface是爲了多態的
如果你看過多繼承,那麽你就明白interface是多餘的,
interface害死人啊,java莫名其妙的來個interface
就是爲了讓那些沒看過c++的人明白怎麽實現多繼承
並且,其實還是一個假的多繼承
忍不住要晒一下观点:interface是约定的contract,对外部调用者的承诺,设计精髓的体现(对象的职责)。良好的interfacer设计可以保证边界清晰、程序的稳定、真正的松耦合。
而Abstract Class是对内部实现的一个基础,最多只是对内部实现提供一些重用而已。或者说,interface关注的是外部的使用者,而Abstract Class是对内的。
并且在复杂的环境下,继承会带来许多副作用。继承层次多,或者扩展点过多时,增加一个子类绝对是一个灾难:需要了解大量父类的内部实现细节,例如经典的Template Method、Strategy等模式。组合应该是更好的实现方式。
我的理解,面向对象更重要的是,保持整体结构的清晰、模块的松耦合。而不是小范围的重用问题。Procedure/Function的重用也可以很好,甚至更简单、容易。
zhangguoli1997
2008-04-18
我认为抽象类跟接口负责的功能是一样的!制定一些接口规范!其它的子类必须实现它们定义的未实现的方法!接口跟抽象类不同的地方是抽象类可以有一些方法里边有代码!当有一些代码是几个子类都有的时候就可以抽象到抽象类!如果没有公用的代码就用接口!就这么简单!
andy54321
2008-04-17
qmy 写道
williamy 写道
1,抽象類就是爲了extends的
2,interface是爲了多態的
如果你看過多繼承,那麽你就明白interface是多餘的,
interface害死人啊,java莫名其妙的來個interface
就是爲了讓那些沒看過c++的人明白怎麽實現多繼承
並且,其實還是一個假的多繼承
2,interface是爲了多態的
如果你看過多繼承,那麽你就明白interface是多餘的,
interface害死人啊,java莫名其妙的來個interface
就是爲了讓那些沒看過c++的人明白怎麽實現多繼承
並且,其實還是一個假的多繼承
.....
这位说的太偏激了。。。。。
现在面向接口的编程不是很好很强大么,大家评价都蛮高的。
如果都用多继承而且没有interface的话,代码的黏合度不是很很高么?
这样对代码的简洁度、解耦合好像都是有些问题的。。
不知道说的对不对
qmy
2008-04-16
public class Cellphone extends Phone implements Bluetooth{
}
卒子99
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){}
}
这样不是会更优雅些吗?
williamy
2008-04-15
1,抽象類就是爲了extends的
2,interface是爲了多態的
如果你看過多繼承,那麽你就明白interface是多餘的,
interface害死人啊,java莫名其妙的來個interface
就是爲了讓那些沒看過c++的人明白怎麽實現多繼承
並且,其實還是一個假的多繼承
2,interface是爲了多態的
如果你看過多繼承,那麽你就明白interface是多餘的,
interface害死人啊,java莫名其妙的來個interface
就是爲了讓那些沒看過c++的人明白怎麽實現多繼承
並且,其實還是一個假的多繼承
卒子99
2008-04-15
是不是我的意思没有表述清楚呢?
大家都在讨论这个到底是什么模式,
其实我只是想表述什么时候选择用接口,什么时候选择用抽象类
大家都在讨论这个到底是什么模式,
其实我只是想表述什么时候选择用接口,什么时候选择用抽象类
卒子99
2008-04-15
dearmite 写道
卒子99 写道
以前在使用接口的时候,就知道它可以抽象系统模型,便于扩展。但到底什么时候使用接口,什么时候使用抽象类,我一直也不是很清楚。但最新做了一个项目,其中遇到抽象一个系统模型的时候,让我明白了他们的用途。废话少说,直接上Case了
需求:从文件中系统中读取数据,可支持从TXT文件,XML,XLS.....
这个抽象层次就比较清楚了,虽然暂时项目中只是从文件中读取数据,但并不保证以后可能会改变啊,抽象出一个接口,就很好满足了OCP。而AbstractFileDataParser类作为项目实际需求,可以实现文件读入流的获取和关闭,实现了一些共同行为。
我想这就是接口和抽象类的最大区别了吧
需求:从文件中系统中读取数据,可支持从TXT文件,XML,XLS.....
这个抽象层次就比较清楚了,虽然暂时项目中只是从文件中读取数据,但并不保证以后可能会改变啊,抽象出一个接口,就很好满足了OCP。而AbstractFileDataParser类作为项目实际需求,可以实现文件读入流的获取和关闭,实现了一些共同行为。
我想这就是接口和抽象类的最大区别了吧
我看了一下楼主的想法,
我的感觉可能和楼主不太一致!
从多种源中读数据,这个肯定是多个实现,不用说了,
如果我来设计,
如果只是读,只有一段代码的话,那就用接口好了,不为别的,干净!
如果是读了之后,还有一段都相同的处理代码,
那就使用抽象类好了。
写两个方法,
abstract String readXML()
{
}
void dealString()
{
String aa = this.readXML();
处理aa;
}
这样不是显得更好样一点???
确实,接口越简单越好,甚至可以只是一个标识接口
但是在实际运用中可以发现,对于这种动名词命令的接口(自己定义的),非常有必须留一个方法用于清除资源,就像Connection, Reader这样的
coreymylife
2008-04-04
确实是模板模式
所谓模板模式就是把一系列类中相同的部分抽取出来形成抽象,不同的方法不同实现!
所谓模板模式就是把一系列类中相同的部分抽取出来形成抽象,不同的方法不同实现!
dearmite
2008-04-04
用抽象类,来实现这种中间多层的实现,
23GOF里,叫模板的模式!
有现成的用别人的成果吧,这样比较省事!
23GOF里,叫模板的模式!
有现成的用别人的成果吧,这样比较省事!
dearmite
2008-04-04
卒子99 写道
以前在使用接口的时候,就知道它可以抽象系统模型,便于扩展。但到底什么时候使用接口,什么时候使用抽象类,我一直也不是很清楚。但最新做了一个项目,其中遇到抽象一个系统模型的时候,让我明白了他们的用途。废话少说,直接上Case了
需求:从文件中系统中读取数据,可支持从TXT文件,XML,XLS.....
这个抽象层次就比较清楚了,虽然暂时项目中只是从文件中读取数据,但并不保证以后可能会改变啊,抽象出一个接口,就很好满足了OCP。而AbstractFileDataParser类作为项目实际需求,可以实现文件读入流的获取和关闭,实现了一些共同行为。
我想这就是接口和抽象类的最大区别了吧
需求:从文件中系统中读取数据,可支持从TXT文件,XML,XLS.....
这个抽象层次就比较清楚了,虽然暂时项目中只是从文件中读取数据,但并不保证以后可能会改变啊,抽象出一个接口,就很好满足了OCP。而AbstractFileDataParser类作为项目实际需求,可以实现文件读入流的获取和关闭,实现了一些共同行为。
我想这就是接口和抽象类的最大区别了吧
我看了一下楼主的想法,
我的感觉可能和楼主不太一致!
从多种源中读数据,这个肯定是多个实现,不用说了,
如果我来设计,
如果只是读,只有一段代码的话,那就用接口好了,不为别的,干净!
如果是读了之后,还有一段都相同的处理代码,
那就使用抽象类好了。
写两个方法,
abstract String readXML()
{
}
void dealString()
{
String aa = this.readXML();
处理aa;
}
这样不是显得更好样一点???
zfms
2008-04-04
楼主写的有些不是很明确,能在完善一些嘛?既然实现了IDataParser 接口,为什么没有接口实现?
发表评论
提醒: 该博客已发表在公共论坛,博客所有留言会成为论坛回贴,留言请注意遵守论坛发贴规则
- 浏览: 21879 次
- 性别:

- 来自: 上海

- 详细资料
搜索本博客
最近加入圈子
最新评论
-
接口,抽象类的使用
楼主需要的接口可以简化为Iterable<YourDataType>
-- by taowen -
接口,抽象类的使用
对于lz的设计我建议 如果是 "多文件格式读取数据"行为,你可以设计成接口如果是 ...
-- by hunter001201 -
接口,抽象类的使用
抽象类与接口的关系,本质是类与接口的关系.到底什么可以划分到类,什么需要借口? ...
-- by hunter001201 -
接口,抽象类的使用
我觉得抽象内和继承相关,比如拿文档类来说,都有title,time属性,并且ge ...
-- by zfyyfz -
接口,抽象类的使用
从面向对象分析与设计的角度来说:abstract class表示“is-a”的关 ...
-- by WorldHello






评论排行榜