从我读到的,接口基本上是方法的类,对吧?如果两个类实现相同的接口,那么它们都应该具有接口中描述的方法。
现在,这有用吗?假设我想调用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");
接口如何帮助?如果没有接口,这不会起作用吗?
由于
答案 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
使用组合和接口的这种组合,您可以将具体类用作AbstractClass
和EventDispatcher
对象。
接口非常适合允许“不相关的对象相互通信”。您可以在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)
本质上,接口主要用于提供对多个不同类中的公共函数的引用,这些类已实现指定的接口。