Chinaunix首页 | 论坛 | 博客
  • 博客访问: 2299303
  • 博文数量: 321
  • 博客积分: 3440
  • 博客等级: 中校
  • 技术积分: 2992
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-24 09:08
个人简介

我就在这里

文章分类

全部博文(321)

文章存档

2015年(9)

2014年(84)

2013年(101)

2012年(25)

2011年(29)

2010年(21)

2009年(6)

2008年(23)

2007年(23)

分类:

2010-08-17 21:58:24

抽象类(Abstract Classes)
        抽象类在工厂和模板方法模式里扮演着重要角色。虽然ActionScript 3.0并没有原生支持它们,但我们依然可以在ActipScript 3.0里套用抽象类和抽象方法的思想。一个抽象类就是一个总被用来继承且永不会直接被实例化的类。它的用途跟接口类相似,但有一个最大的不同之处就是:接 口类只定义公有方法的名称而没有具体的执行(就像是只有函数名而没有函数体),但抽象类两者都有。
        抽象类使用抽象方法,这些抽象方法没有具体的执行,只用作占位符。在其它语言,例如 C#、Java,你可以使用 abstract 关键字来声明抽象方法,它的子类必须重写这些抽象方法。但在ActionScript 3.0里并没有 abstract 关键字,所以我们得想办法解决此问题。
        在ActionScript 3.0里使用抽象类,你必须知道两个特别的关键字:override 和 final。子类必须使用override关键字重写抽象类的方法,方法名称必须相同。使用final关键字来声明那些不被子类重写的方法,在模板方法模 式里就用到final关键字了。

模板方法
        定义在抽象类里的模板方法包含一些方案,这些方案来用组织抽象方法。请看以下这个抽象类,在initialize()方法里,我们定义 games 初始化的方式:

  1. package com.peachpit.aas3wdp.factoryexample {
  2.  
  3.         public class AbstractGame {
  4.  
  5.                 // 模板函数
  6.                 public final function initialize():void {
  7.                         createField();
  8.                         createTeam("red");
  9.                         createTeam("blue");
  10.                         startGame();
  11.                 }
  12.  
  13.                 public function createField():void {
  14.                         throw new Error("Abstract Method!");
  15.                 }
  16.  
  17.                 public function createTeam(name:String):void {
  18.                         throw new Error("Abstract Method!");
  19.                 }
  20.  
  21.                 public function startGame():void {
  22.                         throw new Error("Abstract Method!");
  23.                 }
  24.         }
  25.  
  26. }

        在上面例子里,initialize() 方法是一个模板函数。它定义了 game 是这样初始化的:首先调用 createField() 方法,然后调用 createTeam() 方法来创建队伍(teams),最后调用 startGame() 方法。然而在这个抽象类里面,这几个函数都没干什么实际的事情。它们是给子类重写的,让子类来决定具体需要做的事情。抽象类都不能被直接实例化,而且抽象 类的方法都必须被重写,所以在上面那三个方法里都放置了 throw 语句,这样就可以防止它们被直接调用了。
        接下来我们创建一个 FootballGame 类来继承 AbstractGame 类。这个子类重写抽象类的方法,然后在 initialize() 方法里被调。

  1. package com.peachpit.aas3wdp.factoryexample {
  2.  
  3.     public class FootballGame extends AbstractGame {
  4.  
  5.         public override function createField():void {
  6.             trace("Create Football Field");
  7.         }
  8.  
  9.         public override function createTeam(name:String):void {
  10.             trace("Create Football Team Named " + name);
  11.         }
  12.  
  13.         public override function startGame():void {
  14.             trace("Start Football Game");
  15.         }
  16.  
  17.     }
  18.  
  19. }

        正如你所看见的,FootballGame 类重写了 createField()、createTeam()以及startGame() 方法,使这些方法更适合 football。然而那个 initialize() 方法没有改变。你可以通过这种方式来写一个 BaseballGame和BastketballGame 类。可以像下面代码那样使用 FootballGame 类:

  1. package com.peachpit.aas3wdp.factoryexample {
  2.  
  3.     import com.peachpit.aas3wdp.factoryexample.FootballGame;
  4.     import flash.display.Sprite;
  5.  
  6.     public class FactoryExample extends Sprite {
  7.  
  8.         public function FactoryExample() {
  9.             // Create an instance of FootballGame
  10.             var game:FootballGame = new FootballGame();
  11.             // Call the template method defined in AbstractGame
  12.             game.initialize();
  13.         }
  14.  
  15.     }
  16.  
  17. }

执行上面的代码输出如下。你可以看到,重写后的方法会在那个模板函数(initialize())里调用,这个模板函数没有改变。

  1. Create Football Field
  2. Create Football Team Named red
  3. Create Football Team Named blue
  4. Start Football Game

        也许你会疑惑抽象类有什么用,现在你应该明白了一些,这样做的好处,很显然,扩展性强,以后 createField()、createTeam()以及startGame() 内容需要更改,我们只要再创建一个子类就可以,不必修改其他应用代码。

阅读(1527) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~