Why does the actionscript3.0 class heirachy fail (sometimes)? - actionscript-3

All Objects in actionscript3.0 inherit from the Object class, but the actionscript3.0 compiler seems not to be smart enough to understand this.
take a look at the following code:
package{
public class TestOne{
public function TestOne(){
var t2: TestTwo = new TestTwo();
trace(t2.toString()); // COMPILE TIME ERROR
trace((t2 as Object).toString(); // [object TestTwo]
var t22 : * = new TestTwo();
trace(t22.toString()); // [object TestTwo]
trace((t22 as Object).toString(); // [object TestTwo]
}
}
}
class TestTwo{}
t2.toString() gives a compile time error because the data type t2 does not include toString(). However, t2 does include toString() because it is an object as (t2 as Object).toString() shows. If we do not give the variable a datatype, like t22, then the problem is never encountered. Why cant the actionscript3.0 compiler relize that t2 is both TestTwo and Object?

This is because
Methods of the Object class are
dynamically created on Object's
prototype. To redefine this method in
a subclass of Object, do not use the
override keyword. For example, a
subclass of Object implements function
toString():String instead of using an
override of the base class.
So if you cast TestTwo to an Object, the compiler knows those methods will be implemented. If you don't cast it, TestTwo does not inherit those methods and so they have not been implemented and will error.
It's a bit of a weird one!

Class inheritance and prototype inheritance are two different things in AS3. Prototype inheritance is as far as I understand included for backwards compatibility with AS2/AS1, and it's prototype inheritance that's providing the toString() method on the variable that's cast to the Object class in your example. The Object prototype has the toString() method, not the Object class. Since the prototype is not present on your TestTwo class, it doesn't have a toString() method. If the toString() method was supplied via class inheritance instead, your example would compile.
So technically, your statement "All Objects in actionscript3.0 inherit from the Object class" is not entirely correct, because of the difference between prototype inheritance and class inheritance. Prototype inheritance is a somewhat esoteric OO concept found in script languages.
Does anyone know the reason why AS3 is designed like this?

Related

Limit argument type to package, possible?

In AS3, the below method accepts a parameter of any type:
public function myFunc(data:*) :void
Is it possible to limit the type to a specific package? Something like this maybe:
public function myFunc(data:(my.package:*)) //Accepts any type from my.package
It is possible, but will only have type control at runtime.
import flash.utils.getQualifiedClassName;
public function myFunc(data:*):void {
if (data is Object) {
var fqcn:String=getQualifiedClassName(data);
if (fqcn.slice(0,10)!='my.package') return; // otherwise work
// work here
} // simple types process if needed
}
This sounds like a design issue. One way to make this work during compile is if the parameter type is a custom class:
public function myFunc(data:MyCustomClass):void
Assuming that all the classes within my.package are varied, you could create a custom base class that extends Object and have all of your classes within my.package extend from this base class. Of course, If, however, the inheritance of your my.package classes is less broad you wouldn't need to reach so far. For example, you should only extend from DisplayObject if all the classes within my.package are of that type.
There may also be a way to accomplish what you want using namespaces, but I'm unsure.

AS3 smarter type definitons

I'm working on a component based engine in AS3 and I've got a function in game object that returns a component based on it's type:
gameObject.Has(Body); //This will return a reference to the gameobjects body component
The problem I'm having is accessing the component. To do so I have to do something like this:
Body(gameObject.Has(Body)).SetVelocity(5);
Does anyone have a better way of doing this?
Edit:
public function Has(type:Class):BaseComponent
{
for each(var component:BaseComponent in m_components)
if (component is type)
return component;
return null;
}
What do you currently have for the return type of Has()?
If you prefer to circumvent type checking. You can have your Has() method return type Object.
public function Has():Object{
...
return anObject;
}
#then you can call any prop/method without throwing type errors.
gameObject.Has(Body).SetVelocity(5)
There is not however a nice way to maintain type checking without casting the var, which you're already doing in your example code.
It seems like your issue is that you're trying to be overly generic in your implementation. This introduces two possible points of failure: on the "in" side, where you could potentially load in a BaseObject for your Body that is not a Body, and on the "out" side, where your gameObject could return an object that is not a Body (the fact that the current implementation is apparently type safe is not a given).
You know that any time you are calling what is essentially a really generic getter that you need it to be returning a specific type of object (because you'll be calling methods on it), so why not make life easier on yourself by just making the explicit getter and setter needed?
Or you could get totally ridiculous and genericize your BaseObject like:
gameObject.has(Body).callMethod('setVelocity').to(5);
We are doing kind of the same thing in our project. But we have another approuch. We have a utility class in our ObjectUtility. The method returns all objects under a specific root object.
public function collectObjectsByType(object:Object, type:Class, results:Array):void
{
}
I can just show the method struct.

AS3 constructor has no method with the same name as the class

I was reading ActionScript 3.0 Abstract Factory Design Pattern: Multiple Products and Factories, and I have the following,
private var busFactory:AbFactory;
busFactory=new BusinessFactory();
Both in BusinessFactory.as and in AbFactory.as there is no method with the same name as the class, only createProductA and createProductB. So, how could busFactory call the constructor with new BusinessFactory ?
The default constructors for both AbFactory and BusinessFactory (which the article shows inherits from AbFactory) are created by the compiler.
If you start to pass arguments to the BusinessFactory() constructor, the compiler will complain about an unexpected argument count. That's when you need to write the constructor yourself. But passing nothing means the default can be used.
Also the reason that you could set a AbFactory to a BusinessFactory means that they share the same heritage.

Why can't an object of abstract class be created?

Here is a scenario in my mind and I have googled, Binged it a lot but got the answer like
"Abstract class has not implemented method so, we cant create the object"
"The word 'Abstract' instruct the compiler to not create an object of the class"
But in a simple class where we have all virtual method, able to create an object???
Also, we can define different access modified to Abstract class constructor like private, protected or public.
My search terminated to this question:
Why we can't create object of an Abstract class?
An abstract type is defined largely as one that can't be created. You can create subtypes of it, but not of that type itself. The CLI will not let you do this.
An abstract class has a protected constructor (by default) allowing derived types to initialize it.
For example, the base-type Stream is abstract. Without a derived type where would the data go? What would happen when you call an abstract method? There would be no actual implementation of the method to invoke.
Because it's abstract and an object is concrete. An abstract class is sort of like a template, or an empty/partially empty structure, you have to extend it and build on it before you can use it.
Take for example an "Animal" abstract class. There's no such thing as a "pure" animal - there are specific types of animals. So you can instantiate Dog and Cat and Turtle, but you shouldn't be able to instantiate plain Animal - that's just a basic template. And there's certain functionality that all animals share, such as "makeSound()", but that can't be defined on the base Animal level. So if you could create an Animal object and you would call makeSound(), how would the object know which sound to make?
It's intended to be used as a base class.
http://msdn.microsoft.com/en-us/library/sf985hc5(VS.71).aspx
The abstract modifier can be used with
classes, methods, properties,
indexers, and events.
Use the abstract modifier in a class
declaration to indicate that a class
is intended only to be a base class of
other classes.
Abstract classes have the following
features:
An abstract class cannot be instantiated.
An abstract class may contain abstract methods and accessors.
It is not possible to modify an abstract class with the sealed modifier, which means that the class cannot be inherited.
A non-abstract class derived from an abstract class must include actual implementations of all inherited abstract methods and accessors.
Abstract classes should have at least one virtual method or property that has no implementation. This is marked with the abstract keyword. Inheriting classes must provide an implementation if they are not abstract themselves. You cannot create an instance of an abstract class because it does not have a complete implementation. If it does, it should not be marked abstract in the first place.
As an addition to the other answers, you may not be able to create an instance of the abstract class, but you can certainly refer to instances of derived types through the abstract type and use methods or properties that are defined within the abstract base.
abstract class A
{
public abstract void D();
public void E() { }
}
class B : A
{
public override void D() { }
}
class C : A
{
public override void D() { }
}
...
A a = new B();
a.D();
a.E();
List<A> list = new List<A>() { new B(), new C() };
Simply speaking, an abstract class is like a shell of a class. Not all the methods have implementations, something like a circuit with some wire segments missing. While the majority of it may be constructed, it is up to the users to stick in the wires and resistors in those segments as they see fit.
As to why Java won't let you create it, part of it is just a failsafe (many abstract classes will function just fine without any additions as long as you don't call unimplemented methods).
If we have a class containing pure virtual function then the class is abstract. If we will create an object of the abstract class and calls the method having no body(as the method is pure virtual) it will give an error. That is why we cant create object of abstract class.
We cannot create object for abstract class bcoz ,mostly abstract class contain "abstract methods" ,so abstract methods are incomplete methods.so we cannot estimate the memory of those methods how much they are going to occupy .This is one of the reason why we cannot create object for abstract class.
Here is a similar StackOverflow question. In short, it is legal to have a public constructor on an abstract class. Some tools will warn you that this makes no sense.
Whats the utility of public constructors in abstract classes in C#?
Actually when we create an object of a normal class we use Constructor to allocate the memory
for that object like
myclass obj=new myclass();
Here using constructorr clr identifies how much memory the object needed depending upon the instance variabless and methods. But in case of abstract classes we cant predict the amount of memory required as we dont implement the abstract methods so its not possible to create object.
When we create a pure virtual function in Abstract class, we reserve a slot for a function in the VTABLE(studied in last topic), but doesn't put any address in that slot. Hence the VTABLE will be incomplete.
As the VTABLE for Abstract class is incomplete, hence the compiler will not let the creation of object for such class and will display an errror message whenever you try to do so.
Source : Study Tonight
The reference studytonight :
When we create a pure virtual function in Abstract class, we reserve a
slot for a function in the VTABLE(studied in last topic), but doesn't
put any address in that slot. Hence the VTABLE will be incomplete.
As the VTABLE for Abstract class is incomplete, hence the compiler
will not let the creation of object for such class and will display an
errror message whenever you try to do so.
Sorry guys...
You can Create object for an abstract class, if and only if that abstract class does not contains any abstract method.
Here is my Example. Copy it and compile and run.
abstract class Example {
void display(){
System.out.println("Hi I am Abstract Class.");
}
}
class ExampleDemo {
public static void main(String[] args) {
Example ob = new Example(){};
ob.display();
}
}
So your answer is yes, we can create object for abstract class if it's no Abstract Method.
Check my program.
I don't agree with the accepted answer. The reason is that we can have body for pure virtual function.
The answer is that :
When we create a pure virtual function in the class, we reserve a slot for a function in the VTABLE, but doesn't put any address in that slot. Hence the VTABLE will be incomplete.
As the VTABLE for Abstract class is incomplete, hence the compiler will not let the creation of object for such class and will display an error message whenever you try to do so.
we can create object for abstract class like this also...
public class HelloWorld
{
public static void main(String args[])
{
Person p = new Person()
{
void eat()
{
console.writeline("sooper..");
}
};
p.eat();
}
}
abstract class Person
{
abstract void eat();
}
every body is writing dat abstract class has some virtual function which has not defined. for dat reason we cant create object, but abstract class is a class with the key word 'abstract' which may or may not have abstract method. i think it is a concept, it does not take any memory for dat. so if we can create an object den a memory will be created which is not possible, for dat reason we can't create object of an abstract class bt we can create reference of it which does not occupy any memory location.

Why do constructors not return values?

Please tell me why the constructor does not return any value. I want a perfect technical reason to explain to my students why the constructor does not have any return type.
What actually happens with the constructor is that the runtime uses type data generated by the compiler to determine how much space is needed to store an object instance in memory, be it on the stack or on the heap.
This space includes all members variables and the vtbl. After this space is allocated, the constructor is called as an internal part of the instantiation and initialization process to initialize the contents of the fields.
Then, when the constructor exits, the runtime returns the newly-created instance. So the reason the constructor doesn't return a value is because it's not called directly by your code, it's called by the memory allocation and object initialization code in the runtime.
Its return value (if it actually has one when compiled down to machine code) is opaque to the user - therefore, you can't specify it.
Well, in a way it returns the instance that has just been constructed.
You even call it like this, for example is Java
Object o = new Something();
which looks just like calling a "regular" method with a return value
Object o = someMethod();
How is a constructor supposed to return a return value? The new operator returns the newly created instance. You do not call a ctor, newdoes it.
MyClass instance = new MyClass();
If the ctor would return a value, like so:
public int MyClass()
{
return 42;
}
Where would you receive the integer?
(I'm biased towards C++, so regarding other languages, take this with a grain of salt.)
Short answer: You don't want to have to explicitly check for success for every single object construction in your code.
Somewhat longer answer: In C++, constructors are called for dynamically as well as for globally and automatically allocated objects. In this code
void f()
{
std::string s;
}
there is no way for the constructor of s (std::string::string()) to return any value. Either it succeeds - then we can use the object, or it throws an exception - the we never get a chance to try to use it.
IMO, that's the way it should be.
A constructor is some method automatically called when you initialize a new instance of an object.
This method is there if you need to initialize your object to a given state and run few default methods.
Actually you can imagine the constructor always return the instance of the object created that would be a good image.
When you call a constructor the return value is the new object:
Point pt = new Point(1,2);
But within the constructor itself, you're not actually creating and returning the object; it's been created before your code starts, you're just setting up the initial values.
Point::Point(int x, int y) {
this->x = x;
this->y = y;
}
The lack of a return type reflects the fact that constructors are used differently than other functions. A return type of null, while technically accurate, doesn't reflect well the fact that the code is used as if it returns an object. However, any other return type would indicate that your code is supposed to return something at the end, which is also incorrect.
Constructor doesn’t return anything not even Void. Though some of the answers have mentioned that Constructor do return reference to the newly created object , which is not true. It’s the new operator that returns the object.
So Why constructor doesn’t return any value
Because its not supposed to return anything. The whole purpose of constructor is to initialize the current state of the object by setting the initial values.
So Why doesn’t it even return Void
This is actually a Design constraint which has been placed to distinguish it from methods. public void className() is perfectly legal in java but it denotes a method and not a constructor. To make the compiler understand that it’s a constructor , it requires a way to distinguish it.
all answers are biased towards C++/Java. there is no reason a constructor does not return a value other than the language design.
look at a constructor in a broader sense: it is a function which constructs a new object. you can write perfectly valid constructors in C:
typedef struct object object;
int object_create( object **this );
this is perfect OOP in C and the constructor returns value (this can also be called a factory, but the name depends on the intention).
however, in order to create an object automatically (to satisfy some type cast, or conversion for example), there have to be some rules defined. in C++, there is an argument-less constructor, which is inferred by the compiler if it is not defined.
the discussion is broader than what we think. Object Oriented Programming is a name which describes a way of thinking about programming. you can have OO in almost any language: all you need is structures and functions. mainstream languages like C++ and Java are so common that we think they define "the way". now look at the OO model in Ada: it is far from the model of C++ but is still OO. i am sure languages like Lisp have some other ways of doing OO.
One point that hasn't yet been discussed is that the constructor of class "foo" must be usable not only when creating instances of foo, but also when creating instances of classes derived from foo. In the absence of generics (which weren't available when Java, C++, or .net were designed) there would be no way for foo's constructor to return an object of any derived class. Therefore, what needs to happen is for the derived-class object to be created via some other means and then made available to foo's constructor (which will then be able to use the object in question as a foo when doing its initialization).
Even though the VM implementation of a constructor isn't to return any value, in practice it kind of does - the new object's reference. It would then be syntactically weird and / or confusing to be able to store one or both of the new object's reference and an additional return value in one statement.
So the reason the constructor doesn't return a value is because it's not called directly by your code, it's called by the memory allocation and object initialization code in the runtime. Its return value (if it actually has one when compiled down to machine code) is opaque to the user - therefore, you can't specify it.
Constructor is not directly called by the user's code. It's called by the memory allocation and object initialization code in the run time. Its value is not visible to the user.
In case of C#, the syntax for declaring object is :
classname objectname= new constructor();
According to this line, if we are using assignment operator(=) then it should return some value. But the main objective of a constructor is to assign values to variables, so when we use a new keyword it creates instance of that class, and constructor assigns values to the variable for that particular instance of object, so constructor returns assigned values for that objects's instance.
We can not call constructors independently. Instead they are automatically called whenever objects are created.
Ex:
MyDate md = new Mydate(22,12,2012);
In above example new will return a memory location which will be held by md, and programatically we can not return multiple values in single statements.
So constructors can not return anything.
From what I know about OO design methodologies, I would say the following:
1)By allowing a constructor to return a value, framework developer would allow the program to crash in an instant where the returned value is not handled. To keep the integrity of the program workflow, not allowing a return value from the initialization of an object is a valid decision. Instead, language designer would suggest/force the coders to use getter/setter - access methods.
2)Allowing the object to return a value on initialization also opens possible information leaks. Specially when there are multiple layer or access modifications applied to the variables/methods.
As you aware that when object is created constructor will be automatically called So now imagine that constructor is returning an int value. So code should like this...
Class ABC
{
int i;
public:
int ABC()
{
i=0;
return i;
}
.......
};
int main()
{
int k= ABC abc; //constructor is called so we have to store the value return by it
....
}
But as you aware that stament like int k= ABC abc; is not possible in any programming language. Hope you can understand.
i found it helpful
This confusion arises from the assumption that constructors are just like any other functions/methods defined by the class. NO, they are not.
Constructors are just part of the process of object creation. They are not called like other member functions.
I would be using Java as my language in the answer.
class SayHelloOnCreation {
public SayHelloOnCreation() {
System.out.println("Hello, Thanks For Creating me!");
}
}
class Test {
public static void main(String[]args) {
SayHelloOnCreation thing = new SayHelloOnCreation(); //This line here, produces an output - Hello, Thanks For Creating me!
}
}
Now let us see what is happening here. in java, we use the new keyword to create an instance of a class. And as you can see in the code, in the line, SayHelloOnCreation thing = new SayHelloOnCreation();, the expression after the assignment operator runs before assignment is done. So using the keyword new, we call the constructor of that class (SayHelloOnCreation()) and this constructor creates an object on the Java Heap. After the object is created, a reference to that object is assigned to the thing reference of type SayHelloOnCreation.
The point that I am trying to keep here is that if constructors were allowed to have a return type, Firstly the strongly typed nature of the language would be compromised (Remember I am speaking about Java here).
Secondly, an object of class SayHelloOnCreation is created here so by default I guess the constructor returns a reference of the same type, to avoid ClassCastException.
A method returns the value to its caller method, when called explicitly. Since, a constructor is not called explicitly, who will it return the value to. The sole purpose of a constructor is to initialize the member variables of a class.