我有两个接口声明具有相同名称但签名不兼容的函数:
interface IDog
{
function bark() : void;
}
interface IAdvancedDog
{
function bark(volume : Number) : void;
}
我需要在同一个类中实现它们,如下所示:
class AlphaDog implements IDog, IAdvancedDog
{
public function bark() : void
{
}
public function bark(volume : Number) : void
{
}
}
当然,这不起作用。在这种情况下,有没有办法消除bark()函数的歧义?例如,C#允许显式接口标记:
class AlphaDog : IDog, IAdvancedDog
{
// ...
void IDog.bark() { }
}
虽然由于函数重载规则,C#中不需要这样做。 AS3中没有超载,有没有其他方法可以解决这个问题?
更新。
1)在课堂定义中缺少'公共'限定符是一个错字。我修好了它。
2)我错过了一个额外的要求,即不能修改接口(为了这个问题的目的)。在实际项目中,它们被定义在两个不同的库中,这些库是大型项目的一部分。多个类实现两个接口(单独)。因此,接口的任何更改都需要对所有这些类进行级联更新,重新编译,测试等等。因此,我想首先找出是否存在没有这种侵入式修改的解决方案。它似乎没有。
答案 0 :(得分:5)
ActionScript 3不支持这样的函数重载。 此外,您没有定义函数是否公开,您将收到编译错误。
在您的情况下,您可以添加默认的NaN,并且只有一个界面。
package{
public class AlphaDog implements IDog
{
public function bark(volume : Number = NaN) : void
{
}
}
}
package{
interface IDog
{
function bark(volume : Number = NaN) : void;
}
}
答案 1 :(得分:0)
The_asMan的回答我认为或多或少是最好的答案,也是这个问题的正确答案。我的答案更多的是可以仔细检查的替代方法,但我认为它值得发布(不要低估我:)。
您可以将卷定义为bark()
方法的参数,但不要将其定义为界面中的属性。这就是你说“但你不能在接口-_-中定义一个属性”的地方,这是真的,所以你可以使用下一个最好的东西,getter和setter方法定义。这是我做的一个例子:
package
{
import flash.display.Sprite;
import flash.events.Event;
public class Main extends Sprite
{
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
var strayDog:IDog = new StrayDog();
var alphaDog:IDog = new AlphaDog();
strayDog.bark(); // output: Bark!
alphaDog.bark(); // output: Bark!
(alphaDog as IAdvancedDog).volume = 1; // output: set volume to 1
alphaDog.bark(); // output: Bark!!!
}// end function
}// end class
}// end package
internal interface IDog
{
function bark():void
}// end interface
internal interface IAdvancedDog extends IDog
{
function get volume():Number
function set volume(value:Number):void
}// end interface
internal class StrayDog implements IDog
{
public function StrayDog() {}
public function bark():void
{
trace("Bark!");
}// end function
}// end class
internal class AlphaDog implements IAdvancedDog
{
private var _volume:Number = 0.5;
public function AlphaDog() {}
public function get volume():Number
{
return _volume;
}// end function
public function set volume(value:Number):void
{
if (value <0 || value > 1)
throw new Error("Error: Volume must be between 0 and 1.");
trace("setting volume to " + value);
_volume = value;
}// end function
public function bark():void
{
if (volume <= 0) trace("...")
else if (volume > 0 && volume <= 0.5) trace("Bark!")
else if (volume > 0.5) trace("BARK!!!");
}// end function
}// end class
这只是一个想法,但我会选择The_asMan的答案,这可能是错的。
<强> [UPDATE] 强>
另一种方法:
package
{
import flash.display.GraphicsGradientFill;
import flash.display.Sprite;
import flash.events.Event;
public class Main extends Sprite
{
public function Main():void
{
if (stage) init();
else addEventListener(Event.ADDED_TO_STAGE, init);
}// end function
private function init(e:Event = null):void
{
removeEventListener(Event.ADDED_TO_STAGE, init);
var strayDog:IDog = new StrayDog();
var alphaDog:IDog = new AlphaDog();
var supremeDog:IDog = new SupremeDog();
strayDog.bark(); // output: Bark!
alphaDog.bark(); // output: Bark!
alphaDog.bark( { volume : 1 } ); // output: BARK!!!
supremeDog.bark(); // output: Bark!
supremeDog.bark( { volume : 1 } ); // output: BARK!!!
supremeDog.bark( { length : 3 } ); // output: Baaark!
}// end function
}// end class
}// end package
internal interface IDog
{
function bark(args:Object = null):Boolean
}// end interface
internal class StrayDog implements IDog
{
public function StrayDog() {}
public function bark(args:Object = null):Boolean
{
var barked:Boolean = true;
if (!args) trace("Bark!");
else barked = false;
return barked;
}// end function
}// end class
internal class AlphaDog extends StrayDog
{
public function AlphaDog() {}
override public function bark(args:Object = null):Boolean
{
var barked:Boolean = true;
if (!super.bark(args))
{
if (args.volume)
{
if (args.volume <= 0) trace("...")
else if (args.volume > 0 && args.volume <= 0.5) trace("Bark!")
else if (args.volume > 0.5) trace("BARK!!!");
else throw new ArgumentError("volume must be between 0 and 1");
}
else
{
barked = false;
}// end if
}// end if
return barked;
}// end function
}// end class
internal class SupremeDog extends AlphaDog
{
public function SupremeDog() {}
override public function bark(args:Object = null):Boolean
{
var barked:Boolean = true;
if (!super.bark(args))
{
if (args.length)
{
if (args.length == 1) trace("Bark!")
else if (args.length == 2) trace("Baark!")
else if (args.length == 3) trace("Baaark!");
else throw new ArgumentError("length must be either 1, 2 or 3");
}
else
{
barked = false;
}// end if
}// end if
return barked;
}// end function
}// end class