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框架接口,定义了一个类可以作为一个可视容器。
铭记代码采用接口这种方法,可让你提高类的重用性。将来开发者能够以接口契约替代新的实现,极大地开拓了扩展的可能性。当我们依着接口编码,到时应用程序中的单元测试会非常容易。在测试中服务,数据类和其它实现用模拟对象可以轻易地被替代。
浙公网安备 33010602011771号