AS3面向对象的概念:多态性(二)

实现接口
接口是使用ActionScript 3多态性的二种方法。不要与图形用户界面搞混了。接口是一种编程语言结构,用于创建的类实现特定的结构。在ActionScript 3,一个类可以实现多个接口。

//IAnimal.as
package
{
        public interface IAnimal
        {
                  function getName():String;
                  function eat():void;
                  function talk():void;
          }
}

首先我们可以看到的是,IAnimal接口声明了几个函数,这些功能与上述Animal抽象类的声明是相同的。只是接口中的函数缺少了public命名空间,以及括号构成的函数体。接口只允许声明公有的函数,你不能在接口中声明,静态或私有属性/方法。为什么不行呢?接口表现为一个契约,让外界对象知道在一个类中实现该接口有什么public公有方法可以访问。由于外部对象不能访问private私有方法,它们也不属于接口。若要实施良好封装,公有属性最好不要在接口中声明。一个类应该管理自己内部的状态,基于这个原因,你可以在接口在声明getters和setters属性,通过类的API访问这些属性。按照这个方法,类仍将维持自身的内部状态:

//this is perfectly valid in an interface
function get myProperty():String;
function set myProperty(v:String):void;

下面的类实现IAnimal接口。请注意,他们没有扩展任何类。此外,实现接口没有必要使用override覆盖语法。他们没有父类,也没有方法需要覆盖。

//Mouse.as
package
{
        public class Mouse implements IAnimal
        {
                  public function Mouse()
                  {
                   }
                  
                  public function getName():String
                  {
                           return "Mouse";
                   }
                  
                  public function eat():void
                  {
                           trace("nom nom nom cheese");
                   }
                  
                  public function talk():void
                  {
                           trace("squeek squeek");
                   }
          }
}

//Pig.as
package
{
        public class Pig implements IAnimal
        {
                  public function Pig()
                  {
                   }
                  
                  public function getName():String
                  {
                           return "Pig";
                   }
                  
                  public function eat():void
                  {
                           trace("nom nom nom poo");
                   }
                  
                  public function talk():void
                  {
                           trace("oink oink");
                   }
          }
}

//Polymorphism.as
package
{
        import flash.display.Sprite;
        
        public class Polymorphism extends Sprite
        {
                  protected var menagerie:Array = [];
                  
                  public function Polymorphism()
                  {
                           //create some animals that implement IAnimal
                           var pig:IAnimal = new Pig();
                           var mouse:IAnimal = new Mouse();
                           
                           menagerie = [ pig, mouse ];
                           
                           //make the IAnimal instances perform
                           for each(var animal:IAnimal in menagerie)
                           {
                                    //animal does its thing
                                    trace(animal.getName() + " implements IAnimal")
                                    animal.eat();
                                    animal.talk();
                                    trace("----");
                            }
                   }
          }
}

你可以从第二个例子看到结果非常相似。在循环中每个IAnima共有一个接口,允许我们访问接口的方法,类的具体实现反而并不重要。

Pig implements IAnimal
nom nom nom poo
oink oink
----
Mouse implements IAnimal
nom nom nom cheese
squeek squeek
----

接口和类继承决不是相互排斥的概念。一个类可以从父类扩展,也可以有一个或多个接口。

//Horse.as
package
{
        public class Horse extends Animal implements IAnimal
        {
                  public function Horse()
                  {
                           super("Horse");
                   }
                  
                  override public function getName():String
                  {
                           return name;
                   }
                  
                  override public function eat():void
                  {
                           trace("nom nom nom hay");
                   }
                  
                  override public function talk():void
                  {
                           trace("nayyyy nayyyy");
                   }
          }
}

Horse类从Animal扩展并实现IAnimal接口。
接口在实践中的应用
上面的例子显然不大有用,除非你模拟农场或动物园。我经常在我们应用程序中使用这些概念。
Services——服务,例如,我最近创建了IImageService接口,由FlickrImageService、 FacebookImageService和 XMLImageService类实现该接口,这些服务实现共同的接口,允许创建一个应用程序配置,他并不关心图像来自哪里。
DataTypes——在Flex框架在随处可见。ArrayCollection 和其它一些集合类实现ICollectionView,它允许你使用实现了ICollectionView接口的类作为Flex许多组件的提供者。
Event Responders——IResponder是Flex框架中的一个接口,使用频率很高。类实现该接口可异步响应远程方法。
Containers——IContainer是Flex框架接口,定义了一个类可以作为一个可视容器。
铭记代码采用接口这种方法,可让你提高类的重用性。将来开发者能够以接口契约替代新的实现,极大地开拓了扩展的可能性。当我们依着接口编码,到时应用程序中的单元测试会非常容易。在测试中服务,数据类和其它实现用模拟对象可以轻易地被替代。

posted @ 2010-07-30 12:30  光着屁股打天下  阅读(904)  评论(0编辑  收藏  举报