Interfaces

Een interface is een verzameling methodedeclaraties waarmee ongerelateerde objecten met elkaar kunnen communiceren. ActionScript 3.0 definieert bijvoorbeeld de interface IEventDispatcher; deze bevat methodedeclaraties waarvan een klasse gebruik kan maken om gebeurtenisobjecten af te handelen. De interface IEventDispatcher zorgt voor een standaardmanier voor objecten om gebeurtenisobjecten aan elkaar door te geven. De volgende code toont de definitie van de interface IEventDispatcher:

public interface IEventDispatcher 
{ 
    function addEventListener(type:String, listener:Function,  
            useCapture:Boolean=false, priority:int=0, 
            useWeakReference:Boolean = false):void; 
    function removeEventListener(type:String, listener:Function,  
            useCapture:Boolean=false):void; 
    function dispatchEvent(event:Event):Boolean; 
    function hasEventListener(type:String):Boolean; 
    function willTrigger(type:String):Boolean; 
}

Interfaces zijn gebaseerd op het verschil tussen de interface van een methode en zijn implementatie. De interface van een methode bevat alle informatie die nodig is om die methode aan te roepen, inclusief de naam van de methode, alle parameters en het retourneringstype. De implementatie van een methode bevat niet alleen de interface-informatie, maar ook de uitvoerbare instructies die het gedrag van de methode uitvoeren. Een interfacedefinitie bevat alleen methode-interfaces en elke klasse die de interface implementeert, is verantwoordelijk voor het definiëren van de implementaties van methoden.

In ActionScript 3.0 implementeert de klasse EventDispatcher de interface IEventDispatcher door alle methoden van de interface IEventDispatcher te definiëren en door hoofdteksten van methoden aan elke methode toe te voegen. De volgende code is een fragment uit de klassendefinitie van EventDispatcher:

public class EventDispatcher implements IEventDispatcher 
{ 
    function dispatchEvent(event:Event):Boolean 
    { 
        /* implementation statements */ 
    } 
 
    ... 
}

De interface IEventDispatcher dient als een protocol dat de instanties EventDispatcher gebruiken om gebeurtenisobjecten te verwerken en ze aan andere objecten door te geven die de interface IEventDispatcher ook hebben geïmplementeerd.

U kunt een interface ook beschrijven door te zeggen dat een interface een gegevenstype op dezelfde manier als een klasse definieert. Een interface kan dan ook net als een klasse als een typeannotatie worden gebruikt. Net als een gegevenstype kan een interface ook met operatoren worden gebruikt, zoals de operatoren is en as, die een gegevenstype vereisen. In tegenstelling tot een klasse kan een interface echter niet worden geïnstantieerd. Door dit verschil denken veel programmeurs dat interfaces abstracte gegevenstypen zijn en klassen concrete gegevenstypen.

Interface definiëren

De structuur van een interfacedefinitie is vergelijkbaar met die van een klassendefinitie, behalve dat een interface alleen methoden zonder hoofdteksten kan bevatten. Interfaces kunnen geen variabelen of constanten bevatten, maar wel getters en setters. Als u een interface wilt definiëren, gebruikt u het trefwoord interface. De volgende interface, IExternalizable, maakt bijvoorbeeld deel uit van het pakket flash.utils in ActionScript 3.0. De interface IExternalizable definieert een protocol voor het serialiseren van een object; dat betekent het converteren van een object naar een indeling die geschikt is voor opslag op een apparaat of voor transport over een netwerk.

public interface IExternalizable 
{ 
    function writeExternal(output:IDataOutput):void; 
    function readExternal(input:IDataInput):void; 
}

De interface IExternalizable wordt gedeclareerd met de toegangsbeheerspecificatie public. Interfacedefinities kunnen alleen met de toegangsbeheerspecificaties public en internal worden gewijzigd. De methodedeclaraties binnen een interfacedefinitie kunnen geen toegangsbeheerspecificaties bevatten.

ActionScript 3.0 volgt een conventie waarin interfacenamen beginnen met een hoofdletter I, maar u kunt elke legale id als een interfacenaam gebruiken. Interfacedefinities worden vaak op het hoofdniveau van een pakket geplaatst. Interfacedefinities kunnen niet binnen een klassendefinitie of binnen een andere interfacedefinitie worden geplaatst.

Interfaces kunnen een of meer andere interfaces uitbreiden. De volgende interface, IExample, breidt bijvoorbeeld de interface IExternalizable uit:

public interface IExample extends IExternalizable 
{ 
    function extra():void; 
}

Elke klasse die de interface IExample uitbreidt, moet niet alleen implementaties voor de methode extra() opnemen, maar ook voor de methoden writeExternal() en readExternal() die zijn overgeërfd van de interface IExternalizable.

Interface in een klasse implementeren

Een klasse is het enige taalelement in ActionScript 3.0 dat een interface kan implementeren. Gebruik het trefwoord implements in een klassendeclaratie om een of meer interfaces te implementeren. Het volgende voorbeeld definieert twee interfaces, IAlpha en IBeta , en een klasse, Alpha, die beide implementeert:

interface IAlpha 
{ 
    function foo(str:String):String; 
} 
 
interface IBeta 
{ 
    function bar():void; 
} 
 
class Alpha implements IAlpha, IBeta 
{ 
    public function foo(param:String):String {} 
    public function bar():void {} 
}

In een klasse die een interface implementeert, moeten de geïmplementeerde methoden het volgende doen:

  • De toegangsbeheer-id public gebruiken.

  • Dezelfde naam gebruiken als de interfacemethode.

  • Hetzelfde aantal parameters hebben, elk met gegevenstypen die overeenkomen met de gegevenstypen van de interfacemethodeparameter.

  • Hetzelfde retourneringstype gebruiken.

    public function foo(param:String):String {}

U hebt niettemin enige flexibiliteit bij het benoemen van de parameters van de methoden die u implementeert. Hoewel het aantal parameters en het gegevenstype van elke parameter in de geïmplementeerde methode overeen moet komen met die van de interfacemethode, hoeven de namen van de parameters niet overeen te komen. In het vorige voorbeeld heeft de parameter van de methode Alpha.foo() de naam param:

Maar de parameter in de interfacemethode IAlpha.foo() heeft de naam str:

function foo(str:String):String;

U hebt tevens enige flexibiliteit met standaardparameterwaarden. Een interfacedefinitie kan functiedeclaraties met standaardparameterwaarden bevatten. Een methode die een dergelijke functiedeclaratie implementeert, moet een standaardparameterwaarde hebben die lid is van hetzelfde gegevenstype als de waarde die is opgegeven in de interfacedefinitie, maar de daadwerkelijke waarde hoeft niet overeen te komen. De volgende code definieert bijvoorbeeld een interface die code bevat met een standaardparameterwaarde 3:

interface IGamma 
{ 
    function doSomething(param:int = 3):void; 
}

De volgende klassendefinitie implementeert de interface Igamma, maar gebruikt een andere standaardparameterwaarde:

class Gamma implements IGamma 
{ 
    public function doSomething(param:int = 4):void {} 
}

De reden voor deze flexibiliteit ligt in het feit dat de regels voor het implementeren van een interface specifiek ontworpen zijn voor het verzekeren van de compatibiliteit tussen gegevenstypen en identieke parameternamen; standaardparameterwaarden zijn niet nodig om dit te realiseren.