Welcome, Guest. Please login or register.
Did you miss your activation email?
31 Jul 2010, 11:36:02 UTC
Forum home
+  flexdeveloper.eu Forum
|-+  Flex and ActionScript 3.0
| |-+  Best Practice, OOP & MVC Frameworks (Moderators: flexy, Jan K, James)
| | |-+  Polymorphism in AS3.0
« previous next »
Pages: [1] Print
Author Topic: Polymorphism in AS3.0 (Read 7696 times)
flexy
flexdeveloper.eu
Guru/Addict FD
*****
Posts: 3,155


Recovering Coffee Addict & Adobe Expert


WWW
« on: 30 May 2008, 13:50:55 UTC »

Loads of people have been cracking-on on their blogs recently about how well AS3.0 lends itseld to polymorphism

but I still don't see a true implementation of polymorphism when the following remains a problem:

1.
Class A – a super class with method abc();
Class B – a subclass of A that has overridden abc() method;

var m:A = new B();

m.abc() => calls abc() from class B;

How can you call abc() from class A?


Also, if I define a method/property in Class B that isn't defined in A, the instance doesn't believe it has that method/property unless I cast it as B.

2.
Class A – a super class;
Class B – a subclass of A that has an additional method def();

var m:A = new B();
m.def() => throws exception
B( m ).def() => is fine


Perhaps this is by design, but it seems casting is the only way to achieve this approach.

Some would argue that (2) should always expect a B, and therefore should always be typed against B rather than A, but this removes abstraction from this implementation. Others would say that both A and B should implement an interface, and m should be typed to the interface, but this would require both A and B to have a definition for def(), when we only need B to have it.

The quest for the best way continues...
« Last Edit: 31 May 2008, 12:04:45 UTC by flexy » Logged

fx.barrett
Newbie FD
*
Posts: 19


Paintball Freak


WWW
« Reply #1 on: 04 Jul 2008, 04:33:32 UTC »

I might not be getting the problem right. Why don't you find it normal not to be able to call abc(); from A ? You never had an instance of the A class, so you can't call it... In B class, you are overriding the function in A, so it's normal to have the result from the class B when you call it... in your example, you weren't instantiating A, you were instantiating class B that is of type A...

Not really seeing the problem, if you want to call A, then instantiate the class A or define a method inside B that calls the original method from A without overriding it...
Logged

-- Art is making something out of nothing and selling it. ( by Frank Zappa )
-- Every child is an artist. The problem is how to remain an artist once he grows up. ( by Pablo Picasso )
fx.barrett
Newbie FD
*
Posts: 19


Paintball Freak


WWW
« Reply #2 on: 04 Jul 2008, 06:02:43 UTC »

And regarding the second problem... If I'm not mistaking then the first thing that Flash does it to look at the definitions inside the type of your instance ( in class A in this case ) and if it finds a math in A with something in B then it calls it ( but B must override it in order to work ). Casting it essentially means that you are telling Flash "don't look for something called def(); inside the type but KNOW that you must look inside B and call that one regardless what you have in A".

I'm not 100% positive that I'm right about this one but from my experience, that how I'd explain it. Maybe search for some articles on adobe.com to get a better understanding of how the whole framework fires code and what it does before it fires anything.

IMHO, everything is OK... It's a different language, you can't start comparing AS to Java or C++ or other OOP languages because it simply was created differently, for a different purpose and with a different architecture... If that's how stuff work in ActionScript then OK, people should learn to use they stuff the way the builders of the language intended, complaining and comparing a language to other languages and saying "this can't be done like there... why isn't this working as it did in there..." and so on is just a waste of time... there are certain workarounds that can be applied to get the same results so I don't really see any problems around here.

Just my 2 cents...
Logged

-- Art is making something out of nothing and selling it. ( by Frank Zappa )
-- Every child is an artist. The problem is how to remain an artist once he grows up. ( by Pablo Picasso )
flexy
flexdeveloper.eu
Guru/Addict FD
*****
Posts: 3,155


Recovering Coffee Addict & Adobe Expert


WWW
« Reply #3 on: 04 Jul 2008, 12:00:05 UTC »

I might not be getting the problem right. Why don't you find it normal not to be able to call abc(); from A ? You never had an instance of the A class, so you can't call it... In B class, you are overriding the function in A, so it's normal to have the result from the class B when you call it... in your example, you weren't instantiating A, you were instantiating class B that is of type A...

Not really seeing the problem, if you want to call A, then instantiate the class A or define a method inside B that calls the original method from A without overriding it...

Polymorphism in it's purest form would allow me to decide which version of abc() I want to use, even from a sub-class. The question is not how I would get abc() from A, as that's quite clear, the discussion is about whether that's truely polymorphism.
Logged

flexy
flexdeveloper.eu
Guru/Addict FD
*****
Posts: 3,155


Recovering Coffee Addict & Adobe Expert


WWW
« Reply #4 on: 04 Jul 2008, 12:07:19 UTC »

And regarding the second problem... If I'm not mistaking then the first thing that Flash does it to look at the definitions inside the type of your instance ( in class A in this case ) and if it finds a math in A with something in B then it calls it ( but B must override it in order to work ). Casting it essentially means that you are telling Flash "don't look for something called def(); inside the type but KNOW that you must look inside B and call that one regardless what you have in A".

I'm not 100% positive that I'm right about this one but from my experience, that how I'd explain it. Maybe search for some articles on adobe.com to get a better understanding of how the whole framework fires code and what it does before it fires anything.

IMHO, everything is OK... It's a different language, you can't start comparing AS to Java or C++ or other OOP languages because it simply was created differently, for a different purpose and with a different architecture... If that's how stuff work in ActionScript then OK, people should learn to use they stuff the way the builders of the language intended, complaining and comparing a language to other languages and saying "this can't be done like there... why isn't this working as it did in there..." and so on is just a waste of time... there are certain workarounds that can be applied to get the same results so I don't really see any problems around here.

Just my 2 cents...

1) ActionScript 3 is derived from ECMAScript, and Flex is being specifically targeted at Java developers wanting to move into RIA development.

2) If developers never questioned the language they work with and the 'higher beings' that you describe, we'd all still think punch-card computing was ace!  Kiss

(http://www-03.ibm.com/ibm/history/exhibits/701/images/141511.jpg)
« Last Edit: 04 Jul 2008, 12:09:11 UTC by flexy » Logged

fx.barrett
Newbie FD
*
Posts: 19


Paintball Freak


WWW
« Reply #5 on: 04 Jul 2008, 12:36:10 UTC »

True, true but I was talking about "comparing languages" not "questioning them" Tongue It's a tiny difference there, I agree that developers must question languages in order to get a better understanding of the language or make some changes due to the "new answers" they found.

Regarding Polymorphism, well, as far as I'm concerned only Java is called "true OOP" and ActionScript is no where near "true OOP" but it is OOP... We might not have "true OOP" in AS but we do have OOP and that's for sure, even if some don't like the way it works in AS but it is polymorphism ( at least from my point of view ).

You can find advantages and disadvantages in all the languages, ActionScript just started getting more mature, give the poor thing a break Tongue Only the simple fact that AS 3.0 exists makes my day... I never got along with AS 2.0, I always felt that AS 2.0 is noobish and badly constructed ( I'm and "order" and "strictness" fan )...

I'm sure that in the following years we'll see AS 4.0, 5.0 and who knows which version that hopefully will change things only into better... maybe, on day, ActionScript can be called a "true OOP" language just like Java, but that day is yet to come Cool
« Last Edit: 04 Jul 2008, 12:38:49 UTC by fx.barrett » Logged

-- Art is making something out of nothing and selling it. ( by Frank Zappa )
-- Every child is an artist. The problem is how to remain an artist once he grows up. ( by Pablo Picasso )
flexy
flexdeveloper.eu
Guru/Addict FD
*****
Posts: 3,155


Recovering Coffee Addict & Adobe Expert


WWW
« Reply #6 on: 04 Jul 2008, 13:30:22 UTC »

Pretty much agreed. So in response to the intial statement: "Loads of people have been cracking-on on their blogs recently about how well AS3.0 lends itseld to polymorphism", how would you define polymorphism in AS3.0?
Logged

fx.barrett
Newbie FD
*
Posts: 19


Paintball Freak


WWW
« Reply #7 on: 04 Jul 2008, 14:43:27 UTC »

I don't think that polymorphism has different definitions in every language. The concept behind polymorphism is the same in every language, just that not all the languages work the same way and IMHO that's the main reason why people tend to discuss such subjects, they were used to something else and don't really understand why it works a bit differently in the new language then in the one they were used to.

I'm sure that if you ( or anyone else ) would have started his programming career with Flash/Flex/ActionScript then he would feel just as weird about Java or C++ ( mostly because he was used to a certain way of doing stuff and he'd feel awkward with technologies that are new to him... languages that require a different way of thinking and different ways of solving problems ) as some feel about ActionScript.

And well, don't forget that ActionScript wasn't designed to do the same stuff Java does ( nor in the same way ). What would have been the point in the language if it would have been a copy of another language? ActionScript is powerful enough to let developers solve complex problems and let some creativity floating in the air... Even if it does not work as other "true OOP" languages, it still gets the job done and it does it quite well.  Cool
« Last Edit: 04 Jul 2008, 14:46:19 UTC by fx.barrett » Logged

-- Art is making something out of nothing and selling it. ( by Frank Zappa )
-- Every child is an artist. The problem is how to remain an artist once he grows up. ( by Pablo Picasso )
flexy
flexdeveloper.eu
Guru/Addict FD
*****
Posts: 3,155


Recovering Coffee Addict & Adobe Expert


WWW
« Reply #8 on: 04 Jul 2008, 14:53:53 UTC »

I think the spirit in which this topic was started has been lost. It wasn't a negative criticism of the language, it was a discussion point on the technicalities of polymorphism in AS3.0. If the conclusion of the discussion is it just gets the job done one way or another, then that doesn't really seem right. This is a Best Practice/OOP board after all. Perhaps drawing parallels to other languages would help in seeing how different the implementations are.
Logged

fx.barrett
Newbie FD
*
Posts: 19


Paintball Freak


WWW
« Reply #9 on: 04 Jul 2008, 15:01:20 UTC »

Yeah, sorry, I got carried a way a bit... As you said, the most important thing is that it gets the job done. I'm not sure if it's a good idea to make parallels with other languages because something that is considered "a good practice" in a certain languages, doesn't mean that it's a good practice in ActionScript too ( due to the fact that we must not ignore the platforms the languages are working on and the types of applications we create with a certain language ).
Logged

-- Art is making something out of nothing and selling it. ( by Frank Zappa )
-- Every child is an artist. The problem is how to remain an artist once he grows up. ( by Pablo Picasso )
flexy
flexdeveloper.eu
Guru/Addict FD
*****
Posts: 3,155


Recovering Coffee Addict & Adobe Expert


WWW
« Reply #10 on: 05 Jul 2008, 18:51:35 UTC »

I agree that the deployment environment should be a consideration, but surely good programming is technology-agnostic and independent of any one programming language?

A very good C# developer once told me that good programmers are like good writers: The good writer can write great, well-structured, stories; but may not be able to write it in anything but English. He can learn another language (over time) and become just as great writing stories in that language. A linguist will be good at a variety of languages, but will never write a great story in any of them.

Compartmentalising languages can create an insular developer perspective. Languages that consider themselves the 'exception' are often proven to be anything but, and end-up being ostracized by the wider developer community... as we saw with earlier versions of ActionScript.
« Last Edit: 01 Aug 2008, 00:05:01 UTC by flexy » Logged

outis
Newbie FD
*
Posts: 6


« Reply #11 on: 26 Jan 2009, 06:48:12 UTC »

This may be an old topic, but there's more to be said.

It's necessary to distinguish the type of an object (i.e. runtime type) from the declared (or derived) type of a variable or an expression.  The former is what a value is; it only exists at runtime.  The latter states what a value could be and exists at compile time.

To put this post on firm ground, here's my understanding of polymorphism: it means a given expression can be evaluated with values of different runtime types substituted for a given name.  In other words, the same operations can be applied to values of different runtime types.

1. [...] How can you call abc() from class A [from an instance of class B]?

In a later post you said:
Polymorphism in it's purest form would allow me to decide which version of abc() I want to use, even from a sub-class. The question is not how I would get abc() from A, as that's quite clear, the discussion is about whether that's truely polymorphism.

With polymorphism, "foo.abc()" is valid as long as "foo" is of a type with method "abc".  There's nothing that says the caller can specify which implementation of "abc" gets called.  In other words, it's up to "foo" to decide how to interpret the call to the "abc" method; to do otherwise violate encapsulation.

My take on 1. makes me suspect we have different definitions of polymorphism.  What's your definition?

Also, if I define a method/property in Class B that isn't defined in A, the instance doesn't believe it has that method/property unless I cast it as B.

That's because even though the object is of runtime type B, the variable is of type A.  You can view the declaration "var m:A" as a contract; "m:A" is a promise that m will handle the methods declared in class A and part of m's layout in memory will conform to what A defines (that is, it has A's properties and states where they can be found).  At runtime, the value of m is an object of type B and thus supports additional methods and additional fields in memory, but none of that matters at compile time.  If you want to be able to apply an operation to a variable, you must list it in the contract (ie the public interface) for the variable's type.

var m:A = new B();
B( m ).def()

Some would argue that (2) should always expect a B, and therefore should always be typed against B rather than A, but this removes abstraction from this implementation.

You need to call "def" on "m" but class "A" doesn't define method "def", so "m" isn't an A.  You've just broken the contract "var m:A".  What do you need, an "A" or an object with method "def"? "m" doesn't have to be a "B", but it can't be an "A".

Basically, your code isn't abstract as you want.  By casting m to type B, you're restricting the applicability of your code just as much as declaring "var m:B".  When designing, don't think in terms of runtime types, think in terms of contracts. 

Note that you could use type sniffing: "if (m is B) {B(m).def()}", but this is usually indicative of a bad design.  OOP principles can be broken, but only with good reason ("getting it to work" is not a good reason as long as there is an alternative).

Others would say that both A and B should implement an interface, and m should be typed to the interface, but this would require both A and B to have a definition for def(), when we only need B to have it.

An alternative would be to make "A" an abstract class, but it sounds like this doesn't match the requirements for the type of situation you're describing.

The solution I'd pick is to define an interface ("IADef") that supports the operations you need ("def" and whatever of A you're looking for) and declare "var m:IADef".


Personally, I find some of the aspect oriented features (such as advice) and functional programming features (such as anonymous functions, HOFs, and closures) that ActionScript (and other ECMAScript implementations) supports to be just as exciting as polymorphism, but that's a whole complex of other topics.

As for "true OOP", make mine Smalltalk.
Logged
flexy
flexdeveloper.eu
Guru/Addict FD
*****
Posts: 3,155


Recovering Coffee Addict & Adobe Expert


WWW
« Reply #12 on: 26 Jan 2009, 10:19:07 UTC »

Thanks for the advice, and for continuing the discussion; I appreciate it  Smiley

Like you say, sniffing (or runtime type checking) creates code smell that really does indicate a 'get it working' approach rather than a best practices one. I also think that abstraction has been compromised in the example I provided.

I think regarding the last example, an abstract class or a modification to the interface that both A and B implement would have to be the 'best' way to proceed. I think you are right that the public interface approach at least preserves encapsulation, preventing the need to cast A as B from a class that implements either.

Re: Smalltalk... you've started a heated discussion between a few people here in the office  Cheesy
Logged

outis
Newbie FD
*
Posts: 6


« Reply #13 on: 06 Feb 2009, 16:09:42 UTC »

Re: Smalltalk... you've started a heated discussion between a few people here in the office  Cheesy
What are people saying?

I might have said Eiffel, but I haven't used it.  Self also looks interesting, but ditto on not using it.  Most other languages I disqualified for not being true (read: pure) OOPLs.  If the question had been "what's your favorite language supporting OOP?" I would have picked something different.  I don't know exactly what, but it would have been different.  Maybe C++, despite it's overly complex semantics, or maybe python.

Back on topic, "polymorphism" is an umbrella term collecting (unrelated?) language features.  We can identify a couple specific types of polymorphism: subtyping/inclusion polymorphism (where the runtime type can be a descendent of a variable's declared type), parametric polymorphism/generic programming, ad-hoc polymorphism/method & function overloading, and method overriding.  You can break some of these categories down even further when classifying polymorphism support in a language.  Note that, in a sense, an untyped language supports parametric polymorphism; for this reason, we can say that ActionScript supports generic programming with untyped expressions but not (yet) with typed expressions.  It also supports subtyping polymorphism & overriding but not overloading.

I think that analysis is valid, but I'm also very tired.
Logged
Pages: [1] Print
« previous next »
Share this on: Twitter Twitter Del.icio.us del.icio.us Digg Digg
Jump to:

©2006-2010 Flexdeveloper.eu/Jodie O'Rourke. All rights reserved.
Adobe®, Adobe® Flash™, Adobe® AIR™ and Adobe® Flex™ are registered trademarks of Adobe Systems Incorporated in the United States and other countries. All rights reserved.

Powered by SMF 1.1.11 | SMF © 2006-2009, Simple Machines LLC