AS3:两个具有相同名称但来自两个接口的不兼容签名的函数

时间:2012-02-02 22:41:30

标签: actionscript-3 actionscript

我有两个接口声明具有相同名称但签名不兼容的函数:

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)我错过了一个额外的要求,即不能修改接口(为了这个问题的目的)。在实际项目中,它们被定义在两个不同的库中,这些库是大型项目的一部分。多个类实现两个接口(单独)。因此,接口的任何更改都需要对所有这些类进行级联更新,重新编译,测试等等。因此,我想首先找出是否存在没有这种侵入式修改的解决方案。它似乎没有。

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