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.
Related
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.
I have an Entity class with a destroy() function.
I also have an Enemy class that extends Entity, and I want to add some lines to the destroy() function.
Is there a way to extend functions in ActionScript 3, or is copy and paste the way to go? Thanks.
You need to mark the method with the override keyword, and from there use the same namespace (public, protected, etc) and name that make up the method you want to override in the class you're extending.
The method must also have the same return type and accept the same arguments
Sample override:
override public function destroy():void
{
// add more code
super.destroy();
}
If you exclude the line which reads super.destroy(), the function within the base class will not be run, and only your new code will be used instead.
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).
I have an AS3 Singleton:
package
{
public class Singleton
{
public function Singleton(enforcer:SingletonEnforcer):void
{
if(!enforcer){throw new Error("Only one instance of Singleton Class allowed.");}
}
private static var _instance:Singleton;
public static function getInstance():Singleton
{
if(!Singleton._instance)
{
Singleton._instance=new Singleton(new SingletonEnforcer());
}
return Singleton._instance;
}
}
}
class SingletonEnforcer{}
Consider prop and func() to be a property and method respectively of the Singleton class.
How should I access them?
1. Make them static and use this:
Singleton.getInstance();
Singleton.prop;
Singleton.func();
2. Not make them static and use this:
Singleton.getInstance().prop;
Singleton.getInstance().func();
Does it matter, or is it just visual prefference?
Thank you.
The reason to use a singleton instance is so that you can have class members used in a (relatively) static way.
I won't get into the arguments over whether or not to use a singleton here, there's a very long debate over whether it's a good pattern or not.
Typically, when singletons are used, you store access to them in a local variable and use them like any other class instance. The primary difference, is instead of using:
foo = new Foo();
You use:
foo = Foo.instance;
//Actionscript supports properties which makes this a self-initializing call
-or-
foo = Foo.getInstance();
Followed by
foo.bar();
foo.baz();
foo.fizz = 'buzz';
This doesn't mean that Foo can't have static members of the class, but the rules for adding static members on a Singleton are the same for adding static members to any other class. If the function belongs to the instance, it should be used on the instance, if it belongs to the class, it should be static.
I'm trying to figure out when it would be appropriate for a class to have both static and non-static functions. AKA:
$obj = new ClassA;
$obj->doOOPStuff();
$something = ClassA::doStaticStuff();
Note: This example is done in PHP, however the question is language agnostic .
It seems that if you have a class that is meant to be instantiated, any functions that can be called statically, most likely belong in another class.
Is there any viable cases where I would have a class that used static AND non-static members?
One example: when Creation has to happen in a specific way.
class Foo {
public:
static Foo* Create(...params...);
private:
Foo();
};
Consider String class in .NET. It contains a non-static Split method which breaks some instance into a string[] and a static Join method, which takes a string[] and transform it into a string again.
A static method is applicable when you don't need to keep any state. So Math.Sin() just depends on its parameters and, given same parameters, output will always be the same. A non-static method can have different behavior is called multiple times, as it can keep a internal state.
If the functionality provided by static methods is relevant to that class and its objects, why not. It is pretty common.
Static method are most often factory methods
public class MyClass {
public static MyClass createMyClass(int a, double b) {..}
public static MyClass createSubclassOfMyClass(int c, boolean cond) {..}
public int calculateThis();
public double calculateThat();
}
Another use is to access some property that is logically bound that that class, but not separately to instances. For example - a cache:
(Note - of course synchronization should be taken into account in this example)
public class MyClass {
public static final Cache cache = new Cache();
public static void putInCacheIfNeeded(Object obj) {..}
public static void replaceInCache(Object obj) {..}
public void doSomethingCacheDependend(Object obj) {
if (something) {
MyClass.putInCacheIfNeeded(obj);
} else {
MyClass.replaceInCache(obj);
}
}
}
(Java language for the examples)
Imagine your constructor has two overloads that both are strings:
public class XmlDocument
{
public static XmlDocument CreateFromFile(string filePath);
public static XmlDocument CreateFromXml(string xml);
}
The static function can provide meaningful name to the constructor.
$dialog = DialogFoo::createOpenDialog();
$dialog = DialogFoo::createDocumentOpenDialog();
$dialog = DialogFoo::createImageOpenDialog();
It could also be used to enforce Singleton pattern.
$dialog = DialogFoo::getInstance()
Static class members are most useful where everything must either be in an object or be in a global scope; they are less useful in a language such as Python that supports module-level scopes.
I use static methods to instantiate new objects when I dont want the to give access to the constructor. I ensure that any necessary preconditions are carried out on the class before creating and object. In this example I have a counter to return how many objects are created, if I have 10 objects I prevent any more from being instantiated.
class foo {
private:
static int count;
foo() {}
public:
static foo bar() {
count++;
if (count<=10){
return new foo;
} else {
return null;
}
Let's assume a class has instance methods, here are some good use case for having static methods too:
For static utility methods
Such methods apply to any instance, for example String.format(String, Object...) in Java.
Use them when you don't want to create a specific instance for the job.
For static factory methods
Factory methods are methods that simply instantiate objects like the getInstance() and valueOf() methods in the Java API. getInstance() is the conventional instantiation method in singletons while valueOf() are often type-conversion methods, like in String.valueOf(int).
Use them to improve performance via object-caching, in interface-based frameworks (like the Collections Framework in Java) where you may want to return a subtype, to implement singletons (cough).
In general, static functions produce functionality highly related to class itself. It may be some helper functions, factory methods etc. In this case all functionality contains in one place, it correspond to DRY principle, increases cohesion and reduces coupling.