actionscript-3: refactor interface inheritance to get rid of ambiguous reference error
imagine there are two interfaces arranged via composite pattern, one of them has a dispose
method among other methods:
interface IComponent extends ILeaf {
...
function dispose() : void;
}
interface ILeaf {
...
}
some implementations have some more things in common (say an id
) so there are two more interfaces:
interface ICommonLeaf extends ILeaf {
function get id() : String;
}
interface ICommonComponent extends ICommonLeaf, IComponent {
}
so far so good. but there is another interface which also has a dispose
method:
interface ISomething {
...
function dispose() : void;
}
and ISomething
is inherited by ICommonLeaf:
interface ICommonLeaf extends ILeaf, ISomething {
function get id() : String;
}
As soon as the dispose
method is invoked on an instance which implements the ICommonComponent
interface, the compiler fails with an ambiguous reference error because ISomething
has a method called dispose
and ILeaf
also has a dispose
method, both living in different interfaces (IComponent, ISomething
) within the inheritace tree of ICommonComponent.
I wonder how to deal with the situation if
- the
IComponent
, theILeaf
and theISomething
can't change. - the composite structure must also wo开发者_开发百科rk for for the
ICommonLeaf
&ICommonComponent
- implementations and the
ICommonLeaf
&ICommonComponent
must conform to theISomething
type.
this might be an actionscript-3 specific issue. i haven't tested how other languages (for instance java) handle stuff like this.
You are searching for a solution to the Diamond Problem. C# has an approach to this but basically I would factor the method "dispose" out of your interfaces and create a new "IDisposable".
If the same name like "id" is used twice, it looks like a problem in your code with an ambiguous name. We started to add prefixes to properties and methods. Imagine you have a property "name" that belongs to two different things. Like the "displayName" and the "uniqueName".
This also helps with auto completion. If a DisplayObject is an ILayoutObject and yout type displayObject.layout
you get everything layout releated.
It seems casting solves the ambiguity even though it's far from neat.
class SomeComponent implements ICommonComponent {}
var c : ICommonComponent = new SomeComponent();
trace(ISomething(c).dispose()); //compiles
trace(IComponent(c).dispose()); //compiles
trace(c.dispose()); //fails
As far as I'm aware, there's no neat way to deal with this problem in Actionscript.
The only thing I can think of is refactoring your interfaces to avoid name clashes, which, admitedly, it's not always possible.
Don't know about Java, but C# has a way to handle this through explicit interface implementation.
精彩评论