Actionscript 3接口 - 我不理解它(初学者问题)

时间:2011-08-20 13:34:54

标签: actionscript-3 interface

从我读到的,接口基本上是方法的类,对吧?如果两个类实现相同的接口,那么它们都应该具有接口中描述的方法。

现在,这有用吗?假设我想调用foo();.

public interface IExample {
    function foo(om:String):void;
}

class HungryClass implements IExample{
    public function foo(om:String):void{
        trace("OM NOM NOM!!! Thank you for feeding me" + om);
    }
}

class FullClass implements IExample{
    public function foo(om:String):void{
        trace("No thanks, I don't want to eat" + om);
    }
}

//somewhere..
instanceOfEitherClass.foo("cake");

接口如何帮助?如果没有接口,这不会起作用吗?

由于

7 个答案:

答案 0 :(得分:5)

假设您有一个继承自抽象类的具体类。在这种情况下,您只需执行以下操作:

public class ConcreteClass extends AbstractClass

现在如果你需要具体的类来继承EventDispatcher类呢?您无法执行以下操作:

public class ConcreteClass extends AbstractClass, EventDispatcher

但是,您可以实现EventDispatcher类的IEventDispatcher接口,然后使用EventDispatcher对象,如下所示:

internal class ConcreteClass extends AbstractClass implements IEventDispatcher
{
    private var _eventDispatcher:EventDispatcher;

    public function ConcreteClass()
    {
        _eventDispatcher = new EventDispatcher(this);

    }// end function

    public function addEventListener(type:String, 
                                     listener:Function, 
                                     useCapture:Boolean = false, 
                                     priority:int = 0, 
                                     useWeakReference:Boolean = false):void
    {
        _eventDispatcher.addEventListener(type, listener, useCapture, priority, useWeakReference);

    }// end function

    public function dispatchEvent(event:Event):Boolean
    {
        return _eventDispatcher.dispatchEvent(event);

    }// end function

    public function hasEventListener(type:String):Boolean
    {
        return _eventDispatcher.hasEventListener(type);

    }// end function

    public function removeEventListener(type:String, 
                                        listener:Function, 
                                        useCapture:Boolean = false):void
    {
        _eventDispatcher.removeEventListener(type, listener, useCapture);

    }// end function

    public function willTrigger(type:String):Boolean
    {
        return _eventDispatcher.willTrigger(type);

    }// end function

}// end class

使用组合和接口的这种组合,您可以将具体类用作AbstractClassEventDispatcher对象。

接口非常适合允许“不相关的对象相互通信”。您可以在here接口上找到更多信息。

答案 1 :(得分:2)

这是一个可以帮助您更好地理解的示例。

public interface IPlayableItem {
  function playMe():void;
}

public class VideoPlayer implements IPlayableItem {
  public function playMe():void {
    //do video playing stuff here
  }
}


public class AudioPlayer implements IPlayableItem {
  public function playMe():void {
    //do audio playing stuff here
  }
}


public class SlideShowPlayer implements IPlayableItem {
  public function playMe():void {
    //do image slideshow stuff here
  }
}

public class Main {
  public var myPlayables:Array = new Array();

  public function Main() {
    buildMyItems();
    runMyItems();
  }

  public function buildMyItems():void {
    myPlayables.push(new VideoPlayer());
    myPlayables.push(new AudioPlayer());
    myPlayables.push(new SlideShowPlayer());
  }

  public function runMyItems():void {
    for each (var item:IPlayableItem in myPlayables) {
       item.playMe();
    }
  }
}

在这种情况下,每个项目如何需要实现每个项目所需的代码并不重要(在这种情况下每个项目都会有明显不同)。但是它提供了一个与每个类进行交互的通用接口,因此对于其他类来说,实现接口的每个类如何实现它所需要的东西并不重要。

答案 2 :(得分:1)

这是一个我自己想知道的问题。通过与同事的讨论(他们也关注同一主题):

  • Interface让你的编译器/运行时知道哪些函数是快速可用的,这取决于语言(和编译器),可能提升性能。
  • 团队环境中,Interface可以让其他开发人员知道需要哪些功能。或许通过名称,他们可以轻松解读其中的功能需求。
  • 与“标准”数据库中的列结构类似,Interface会将您整齐地锁定到多个类的相同方法布局中。这对于具有大量* extend * ing和/或多态性的大项目来说非常方便,因为如果错过了方法实现,编译器将“提醒”你。

此外, Senocular one of his OOP artciles中涵盖了此内容。对于AS3来说,他是一个聪明人。

答案 3 :(得分:1)

看起来很多人都试图在这里解释接口的使用,但不知何故我觉得这里没有捕获接口的真正用途。虽然在任何面向对象的分析和设计书中都很好地解释了这一点,但我在下面用自己的话说。

根据我的说法,接口的主要用途之一是使“插件”架构成为可能。什么是插件?插件是一种扩展基本应用程序功能的逻辑,无需重新编译基本应用程序。简而言之,有人定义了一次接口,而其他人编写了他们的代码来实现该接口,可以将他们的新代码插入到旧应用程序中,并根据他们的选择进行扩展。

例如,让我们来看看音乐播放器Winamp的流行案例。 Winamp的开发人员定义了一种架构,允许创建插件来执行各种操作。例如,您可能有一个插件将当前正在播放的MP3写为wav文件。或者是一个“虚拟环绕”插件,它采用普通的mp3并使其听起来更好。

这里需要注意的是,Winamp的开发者可能没有想到他的玩家可以“扩展”来做某件事。他本来就已经定义了插件可以完成的所有操作。例如,他可能已经定义了一个接口IMusicOperation,如下所示

public interface IMusicOperation
{
   function Play():void;
   function Pause():void;
   function TrackSeekTo(offset:double):void;  
}

当我作为插件开发人员实现此界面时,它允许我以任何我想要的方式控制Winamp。例如,我可能有一个允许某人从远程位置控制Winamp的Web服务。

我觉得有用的另一个实用类比是用于在游戏中驾驶车辆的界面。

public interface IDriveVehicle
{
  function Start():void;
  function Stop():void;
  function TurnLeft():void;
  function TurnRight():void;
}

现在,最重要的是,如果任何车辆(无论是火箭,宇宙飞船,汽车,自行车,船,潜艇)都实现了这个界面,我的游戏代码可以操纵这辆车而无需了解更多信息。最重要的是,即使在我的游戏上市几年之后,有人可以通过创建符合我的IDriveVehicle界面的插件为我的游戏“添加”新的太空船。

它还允许我的应用程序在运行时加载组件,这些组件支持我公开的接口。

有关详细信息,这看起来像一个很好的链接...... http://www.cs.utah.edu/~germain/PPS/Topics/interfaces.html

希望这有帮助,

答案 4 :(得分:0)

是的,这可以不用连接。

我认为当你想将类推送到向量时更有用。你可以制作这样的矢量:

var myExampleList:Vector.<IExample> = new Vector.<IExample>();
myExampleList.push(new HungryClass());
myExampleList.push(new FullClass());

答案 5 :(得分:0)

食物类比在编程中被过度使用,但我喜欢将界面视为食谱的必要成分,因此界面可以作为课堂设计的指南。

public interface IChocolateChipCookies
{
     function butter(amount:Number):void;
     function sugar(amount:Number):void;
     function eggs(amount:Number):void;
     function vanillaExtract(amount:Number):void;
     function flour(amount:Number):void;
     function water(amount:Number):void;
     function salt(amount:Number):void;
     function walnuts(amount:Number):void;
     function chocolateChips(amount:Number):void;
}

然后在你的班级中使用该界面:

public class BakeCookies extends Sprite implements IChocolateChipCookies
{
     public function BakeCookies()
     {

     }

     //must include all functions (ingredients) from IChocolateChipCookies
     //in this class in order to make the cookies correctly!

     private function butter(amount:Number):void
     {

     }

     private function sugar(amount:Number):void
     {

     }

     private function eggs(amount:Number):void
     {

     }

     private function vanillaExtract(amount:Number):void
     {

     }

     private function flour(amount:Number):void
     {

     }

     private function water(amount:Number):void
     {

     }

     private function salt(amount:Number):void
     {

     }

     private function walnuts(amount:Number):void
     {

     }

     private function chocolateChips(amount:Number):void
     {

     }
}

答案 6 :(得分:-3)

本质上,接口主要用于提供对多个不同类中的公共函数的引用,这些类已实现指定的接口。