就像许多前辈都指出的“尽量使用接口而不是抽象类”,我从中有所感悟,用我前面举的抽象类的例子来解释一下如何用接口替换抽象类(专门写这篇,是想看看我是不是真正理解了-只有能表达出来的东西才算你真正理解,背诵不算:),呵呵)
不提倡使用抽象类的原因是因为你一旦继承了这个类就是这个类型了(被定义了一种语义),就像前面我举的关于内核的例子,你继承了AbstractBrowserCore,那么它就代表了一种浏览器的内核。因为不管java还是as它们都是单继承的,也就是只有一个父类,父类的定义显然是很宝贵的,不能随随便便的来定义。
我在前面的例子上再举个例子:
像FF和IE都提供了很多不错的插件(ActiveX),这么好的资源不能浪费啊!!!我决定不只是利用其它浏览器的内核,它们的插件我也要!还有其它功能(如书签什么的),我准备把它作成服务。
这些服务包括:
使用其它浏览器的内核,使用浏览器插件,得到浏览器书签等等。
上面每个功能我都用接口来定义:
[code:php]
interface IBrowse
{
function browse(url:String):String;
function back():void;
function forward():void;
function home():void;
}
interface IPlugin
{
function getPlugins():Array;
function invoke(plugin:Object):Boolean;
}
interface IBookmark
{
function addBookmark(b:Object):void;
function getBookmarks():Array;
}
我用一个FFBrowserService来实现前面定义的所有接口(只用FF来举例):
public class FFBrowserService implements IBrowse, IPlugin, IBookmark
{
public ovarride function browse(url:String):String
{
// 调用FF的api
}
.........
// 实现的所有接口方法
..........
}
使用 FFBrowserService类:
public class BrowserApp
{
private var _browserService:Object;
private var _bookmark:Array;
public function set browserService(bs:Object):void
{this._browserService = bs;}
public function init()
{
if(this._browser is IBookmark)
{
var bm:IBookmark = this._browserService as IBookmark;
this._bookmark = bm.getBookmarks();
}
}
public function onBackBtRelease():void
{
if(this._browserService is IBrowse == false) return;
var b:IBrowse = this._browserService as IBrowse;
b.back();
}
public function onEnterRelease():void
{
if(this._browserService is IBrowse == false) return;
var b:IBroser = this._browserService as IBrowse;
checkStatus(b.browse(inputText.text)); //检查http状态
}
public function pluginOnRelease(pl:Object):void
{
if(this._browserService is IPlugin == false) return;
var p:IPlugin = this._browserService as IPlugin;
p.invoke(pl);
}
}
[/code]
像这样用接口而不是用抽象类是不是觉得更加的灵活呢?假设一种浏览器不支持插件,那么可以不用实现IPlugin这个接口。而从语义上来讲,FFBrowserService这个类代表了整个第三方浏览器所提供的服务,而不仅仅是内核而已。
希望我的理解对你有所帮助:)