Super interface and super class having the same method name - actionscript-3

I am trying to create a spark datagrid item renderer. This item renderer extends a checkbox, and implements IGridItemRenderer
public class CellCheckBoxItemRenderer extends CheckBox implements IGridItemRenderer
When I implement IGridItemRenderer, I need to implement the interface methods, I am having a problem with the following methods:
public function get hovered():Boolean
{
}
public function set hovered(value:Boolean):void
{
}
since the methods are inherited as well from the checkbox
EDIT
The signatures of the functions
//spark checkbox signature
protected function get hovered():Boolean
protected function set hovered(value:Boolean):void
and the signature above belongs to the interface IGridItemRenderer

I guess the implementation of IGridItemRenderer is the more important part, so you can use it in a datagrid. The CheckBox provides just the functionality, you don't have to extend it if there are conflicts in my opinion.
public class CellCheckBoxItemRenderer implements IGridItemRenderer {
private var checkBox:CheckBox;
public function getCheckBox {
return checkBox;
}
//...
}
If CheckBox would implement any useful interfaces, you could also implement them in your renderer and delegate the methods to the checkbox, which may let you encapsulate the whole checkbox. That's not the case here though.

The problem is that interfaces, by design, only specify the signature for public functions, whereas the function in Checkbox is set as protected.
The only solutions:
remove the interface/Checkbox class from CellCheckBoxItemRenderer
remove the declaration from the interface
change Checkbox so hovered is a public property
it might be possible to change the accessor dynamically using the as3 commons bytecode project (http://www.as3commons.org/as3-commons-bytecode/emit.html), but I'm not 100% sure.

Related

Any alternative to injecting Castle Windsor typed factories?

Most of my components are registered using the code-based (fluent) approach, but there is one particular component that I need to resolve differently at runtime. This is the interface and a couple of concrete implementations:-
public interface ICommsService ...
public class SerialCommsService : ICommsService ...
public class TcpCommsService : ICommsService ...
Some of our users will need the serial service while others will need the TCP service. My current solution (which works btw) is to use a typed factory and a custom component selector - the latter reads an app.config setting to determine which implementation the typed factory will resolve and return.
First the typed factory (nothing special about this):-
public interface ICommsServiceFactory
{
ICommsService Create();
void Release(ICommsService component);
}
Next, the custom component selector, which reads the fully-qualified type name from app.config (e.g. "MyApp.SomeNamespace.TcpCommsService"):-
public class CommsFactoryComponentSelector : DefaultTypedFactoryComponentSelector
{
protected override string GetComponentName(MethodInfo method, object[] arguments)
{
return ConfigurationManager.AppSettings["commsServiceType"];
}
}
Then the registration stuff:-
var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<ITypedFactoryComponentSelector>()
.ImplementedBy<CommsFactoryComponentSelector>());
container.Register(Component.For<ICommsFactory>()
.AsFactory(o => o.SelectedWith<CommsFactoryComponentSelector>()));
container.Register(Component.For<ICommsService>()
.ImplementedBy<SerialCommsService>().LifeStyle.Singleton);
container.Register(Component.For<ICommsService>()
.ImplementedBy<TcpCommsService>().LifeStyle.Singleton);
Finally, an example class with a dependency on ICommsService:-
public class Test
{
public Test(ICommsFactory commsFactory)
{
var commsService = commsFactory.Create();
...
}
}
As already mentioned, the above solution does work, but I don't like having to inject the factory. It would be more intuitive if I could just inject an ICommsService, and let something somewhere figure out which implementation to resolve and inject - similar to what I'm doing now but earlier in Windsor's "resolving pipeline". Is something like that possible?
You can use UsingFactoryMethod here:
container.Register(Component.For<ICommsService>().UsingFactoryMethod(kernel => kernel.Resolve<ICommsServiceFactory>().Create()));
You can inject ICommsService to any class now. ICommsServiceFactory can be a simple interface now:
interface ICommsServiceFactory
{
ICommsService Create();
}

ActionScript 3 Override Methods + Increase Visibility

When I extend a class I want to override methods and change their accessibility like a protected method should be public in a certain class. When I compile it says: "Incompatible override". I can't reduce nor can I increase the visibility.
Reducing wouldn't make sense and I don't need it but I was able to increase method visibility in Java. Why not in ActionScript 3 ?
public class OldClass
{
protected function doStuff() : void
{}
}
public class NewClass extends OldClass
{
override public function doStuff() : void
{}
}
Am I doing something wrong ?
No, you're not doing anything wrong. That's just how the language works. From the documentation (emphasis added):
Static methods are not inherited and cannot be overridden. Instance methods, however, are inherited by subclasses and can be overridden as long as the following two criteria are met:
...
The override method must have the same level of access control as the base class method. Methods marked as internal have the same level of access control as methods that have no access control specifier.
The override method must have the same number of parameters as the base class method.
The override method parameters must have the same data type annotations as the parameters in the base class method.
The override method must have the same return type as the base class method.

Getting Error when working with ActionScript Class and Interface in FLEX 3, ActionScript 3.0

I am currently new in ActionScript and I am creating an Interface and Class where class implements Interface.
I have created Interface and Class both in src/com folder. Here is the code what I did till now.
Interface
package com
{
public interface TestData
{
function getInput(str:String):void
function getOutput():String
}
}
Class
package com
{
public class EntityEL implements TestData
{
public var uname:String;
function getOutput():String
{
return uname;
}
function getInput(str:String):void
{
uname = str;
}
public function EntityEL()
{
}
}
}
mxml file
public var etn:EntityEL = new EntityEL();
public function btnClick():void
{
etn.getInput(value.text);
Alert.show(etn.getOutput());
}
<mx:Button label="Button Click" click="{btnClick();}" />
<mx:TextInput id="value" />
I am getting an error "1044: Interface method getInput in namespace com:TestData not implemented by class com:EntityEL."
Please Help me to solve this problem.
The idea of an interface is to define a contract between the caller and callee objects: Which methods can be accessed, which parameters are required, and what kind of data will be returned.
In order for that contract to make any sense, these methods have to be accessible, so that the "outside world" is allowed to call them.
When you omit access modifiers, the Flex compiler assumes internal as the default, which means that classes from within the same package have permission to access the methods - and so to some extent, this contract seems fulfilled. The same would be true for any other namespace.
Strangely enough, Adobe clearly doesn't allow it: Your method implementations have to be public.
However, you can declare your interface as internal, so that only classes from the package are allowed to implement it, and that leaves a way to keep your API internal, as well - if that was your intent.

How can I create a subclass that takes in different parameters for the same function name?

So I have made this simple interface:
package{
public interface GraphADT{
function addNode(newNode:Node):Boolean;
}
}
I have also created a simple class Graph:
package{
public class Graph implements GraphADT{
protected var nodes:LinkedList;
public function Graph(){
nodes = new LinkedList();
}
public function addNode (newNode:Node):Boolean{
return nodes.add(newNode);
}
}
last but not least I have created another simple class AdjacancyListGraph:
package{
public class AdjacancyListGraph extends Graph{
public function AdjacancyListGraph(){
super();
}
override public function addNode(newNode:AwareNode):Boolean{
return nodes.add(newNode);
}
}
Having this setup here is giving me errors, namely:
1144: Interface method addNode in namespace GraphADT is implemented with an incompatible signature in class AdjacancyListGraph.
Upon closer inspection it was apparent that AS3 doesn't like the different parameter types from the different Graph classes newNode:Node from Graph , and newNode:AwareNode from AdjacancyListGraph
However I don't understand why that would be a problem since AwareNode is a subClass of Node.
Is there any way I can make my code work, while keeping the integrity of the code?
Simple answer:
If you don't really, really need your 'addNode()' function to accept only an AwareNode, you can just change the parameter type to Node. Since AwareNode extends Node, you can pass in an AwareNode without problems. You could check for type correctness within the function body :
subclass... {
override public function addNode (node:Node ) : Boolean {
if (node is AwareNode) return nodes.add(node);
return false;
}
}
Longer answer:
I agree with #32bitkid that your are getting an error, because the parameter type defined for addNode() in your interface differs from the type in your subclass.
However, the main problem at hand is that ActionScript generally does not allow function overloading (having more than one method of the same name, but with different parameters or return values), because each function is treated like a generic class member - the same way a variable is. You might call a function like this:
myClass.addNode (node);
but you might also call it like this:
myClass["addNode"](node);
Each member is stored by name - and you can always use that name to access it. Unfortunately, this means that you are only allowed to use each function name once within a class, regardless of how many parameters of which type it takes - nothing comes without a price: You gain flexibility in one regard, you lose some comfort in another.
Hence, you are only allowed to override methods with the exact same signature - it's a way to make you stick to what you decided upon when you wrote the base class. While you could obviously argue that this is a bad idea, and that it makes more sense to use overloading or allow different signatures in subclasses, there are some advantages to the way that AS handles functions, which will eventually help you solve your problem: You can use a type-checking function, or even pass one on as a parameter!
Consider this:
class... {
protected function check (node:Node) : Boolean {
return node is Node;
}
public function addNode (node:Node) : Boolean {
if (check(node)) return nodes.add(node);
return false;
}
}
In this example, you could override check (node:Node):
subclass... {
override protected function check (node:Node) : Boolean {
return node is AwareNode;
}
}
and achieve the exact same effect you desired, without breaking the interface contract - except, in your example, the compiler would throw an error if you passed in the wrong type, while in this one, the mistake would only be visible at runtime (a false return value).
You can also make this even more dynamic:
class... {
public function addNode (node:Node, check : Function ) : Boolean {
if (check(node)) return nodes.add(node);
return false;
}
}
Note that this addNode function accepts a Function as a parameter, and that we call that function instead of a class method:
var f:Function = function (node:Node) : Boolean {
return node is AwareNode;
}
addNode (node, f);
This would allow you to become very flexible with your implementation - you can even do plausibility checks in the anonymous function, such as verifying the node's content. And you wouldn't even have to extend your class, unless you were going to add other functionality than just type correctness.
Having an interface will also allow you to create implementations that don't inherit from the original base class - you can write a whole different class hierarchy, it only has to implement the interface, and all your previous code will remain valid.
I guess the question is really this: What are you trying to accomplish?
As to why you are getting an error, consider this:
public class AnotherNode extends Node { }
and then:
var alGraph:AdjacancyListGraph = new AdjacancyListGraph();
alGraph.addNode(new AnotherNode());
// Wont work. AnotherNode isn't compatable with the signature
// for addNode(node:AwareNode)
// but what about the contract?
var igraphADT:GraphADT = GraphADT(alGraph);
igraphADT.addNode(new AnotherNode()); // WTF?
According to the interface this should be fine. But your implemenation says otherwise, your implemenation says that it will only accept a AwareNode. There is an obvious mismatch. If you are going to have an interface, a contract that your object should follow, then you might as well follow it. Otherwise, whats the point of the interface in the first place.
I submit that architecture messed up somewhere if you are trying to do this. Even if the language were to support it, I would say that its a "Bad Idea™"
There's an easier way, then suggested above, but less safe:
public class Parent {
public function get foo():Function { return this._foo; }
protected var _foo:Function = function(node:Node):void { ... }}
public class Child extends Parent {
public function Child() {
super();
this._foo = function(node:AnotherNode):void { ... }}}
Of course _foo needs not be declared in place, the syntax used is for shortness and demonstration purposes only.
You will loose the ability of the compiler to check types, but the runtime type matching will still apply.
Yet another way to go about it - don't declare methods in the classes they specialize on, rather make them static, then you will not inherit them automatically:
public class Parent {
public static function foo(parent:Parent, node:Node):Function { ... }}
public class Child extends Parent {
public static function foo(parent:Child, node:Node):Function { ... }}
Note that in second case protected fields are accessible inside the static method, so you can achieve certain encapsulation. Besides, if you have a lot of Parent or Child instances, you will save on individual instance memory footprint (as static methods therefore static there exists only one copy of them, but instance methods would be copied for each instance). The disadvantage is that you won't be able to use interfaces (can be actually an improvement... depends on your personal preferences).

Friend methods/classes for AS3 packageless classes

Hi I'm wondering if I can have a packageless () AS3 class call a private method on the main class in the file. For example:
package demo
{
public class MyDemoClass
{
var helper:FriendlyHelperClass = new FriendlyHelperClass(this)
}
private function methodToCall():void
{
...
}
}
public class FriendlyHelperClass
{
public function FriendlyHelperClass(demo:MyDemoClass)
{
demo.methodToCall()
}
}
The call to methodToCall() from FriendlyHelperClass will fail as it is a private member of the MyDemoClass. Is there any way to call the methodToCall() method from the FriendlyHelperClass without extending MyDemoClass.
Basically I'm looking for inner class functionality that Java has or some sort of C++ style friend class.
Short answer : no.
You can never access a private member from outside a class in ActionScript. What you could do is use a namespace instead of a private scope. This would allow to give access to some members to selected classes. This is the closest of a friend class that you will get in AS3.
I'm afraid that is not possible, but if you make the class dynamic, then you can edit it while the program is running, and possibly add some useful functions to it, to access the private functions. I haven't tried it though.
Dynamic classes
Without testing the code, and knowing what your full problem. you can try passing the functions you need into the embedded class as a callback. e.g.,
helper.methodToCallCallback = this.methodToCall;
then inside FriendlyHelperClass:
this.methodToCallCallback();