Join 307,219 C++ Programmers for FREE! Get instant access to thousands of C++ experts, tutorials, code snippets, and more! There are 1,650 people online right now. Registration is fast and FREE... Join Now!
class Dog : public Animal { public: Dog(const string& name) : Animal(name) { } virtual const string talk() { return "Arf! Arf"; } };
// prints the following: // // Missy: Meow! // Mr. Bojangles: Meow! // Lassie: Arf! Arf! // int main() { Animal* animals[] = { new Cat("Missy"), new Cat("Mr. Bojangles"), new Dog("Lassie") };
for(int i = 0; i < 3; i++) cout << animals[i]->name << ": " << animals[i]->talk() << endl;
return 0; }
However, I can see the flip side of function overloading:
QUOTE
The primary usage of polymorphism in industry is the ability of objects belonging to different types to respond to method, field, or property calls of the same name, each one according to an appropriate type-specific behavior. The programmer (and the program) does not have to know the exact type of the object in advance, and so the exact behavior is determined at run time (this is called late binding or dynamic binding).
To some extent that could be considered polymorphism since we provide many overloaded functions because we may not know which will be called at run time.
Discuss.
This post has been edited by NickDMax: 3 May, 2009 - 07:05 AM
When I think polymorphism, I think class inheritance. I don't look at function overloading as polymorphism. To me function overloading is what it says, function overloading and nothing more.
I've read that both are true because they change the way an object behaves. I believe that the word polymorph can be interpreted to mean: 'to change form'.
I've been researching it since the topic came up in the C# forums. This is the best definition I've found:
QUOTE
Through inheritance, a class can be used as more than one type; it can be used as its own type, any base types, or any interface type if it implements interfaces. This is called polymorphism.
*edit* Like in KYA's program post. Animal is a base type and is transformed into cats and dogs. I think that is a very good way to demonstrate it.
So I guess technically speaking overloading doesn't really fit into the category because it doesn't change the way the object behaves, just how you tell the object to do something.
I think it can be a confusing topic for somebody new to OOP.
This post has been edited by SixOfEleven: 2 May, 2009 - 07:53 PM
At the bottom of the summary of that article you find the following paragraph:
QUOTE
Polymorphism is not the same as method overloading or method overriding. Polymorphism is only concerned with the application of specific implementations to an interface or a more generic base class. Method overloading refers to methods that have the same name but different signatures inside the same class. Method overriding is where a subclass replaces the implementation of one or more of its parent's methods. Neither method overloading nor method overriding are by themselves implementations of polymorphism.
The sources for that information are obviously experts in the field being Kathy Sierra and, of course, Bjarne Stroustrup himself. The paragraph singles out method overloading (aka function overloading) as not being an implementation of polymorphism. I also agree with the statement completely. I can see why a beginner might find the topic confusing but I think any experienced programmer would agree that function overloading is clearly not an example of polymorphism.
I also stated that I do not agree with function overloading as being polymorphism. If you looked at the reference thread you can see why I posed the question.
edit: Some have referred to it as compile time polymorphism, I was just curious to see who thought that was applicable.
This post has been edited by KYA: 2 May, 2009 - 07:32 PM
I also stated that I do not agree with function overloading as being polymorphism. If you looked at the reference thread you can see why I posed the question.
I didn't say I was disagreeing with you. To the contrary... I was absolutely agreeing with you. I was simply adding to the conversation... or at least that was my intention.
The only reason I mentioned sourcing wikipedia for your content is because you posted the content without any mention of where it came from. That leads to comments like this:
After reading the reply in C# forums, I googled 'polymorphism' and object-oriented concepts. The sites all lead to the conclusion that overloading is not what the term polymorphism was meant to cover. The only reason that it stuck with me is a prof and a couple books said it was.
I just take polymorphism to mean what its name implies. You have a class, and then you have many different inherited forms from it. They all have the same sort of actions, but act differently.
And I contributed in that other thread because I had recently heard of this "compile-time polymorphism," and when I read SixOfEleven's post regarding operator overloads being an example of polymorphism it rang that bell.
I agree that the true meaning of polymorphism is only represented by objects being able to change their behavior at run-time, and that this "compile-time polymorphism" is a bastardization of the concept. I believe this idea may have originated in countries where English is not the primary language -- based on the Google results I found -- and could actually be the result of misunderstandings not so much in the C++/C# language, but rather communication via English.
It's important to understand that polymorphism is a concept, and idea, rather than any particular programming language construct. All object oriented concepts, and computer science concepts in general, are like this. As programmers, we tend to think in terms of code rather than theory, it just makes more sense that way. It's like the difference between a problem described in words (theory) and actually seeing the numbers (program).
An "object" is just a code abstraction. It's a collection of functions and variables clumped together so mere mortals can work at a higher level without being bothered by all the details. In a sense, operator overloading is a reasonable side effect of implementing some kind of class mechanism.
Let's imagine I have plain old C and I want to add classes to it. I start with structs. What I really need to be able to do is write something like:
To do that, I need operator overloading. Once I have that, my friendly parser can take "cat.talk()" and make it into "talk(&cat)" simply. Of course, I don't need operator overloading for this, I can just pass a void pointer and worry it out at that level. But if I have it, I might as well expose it.
I tend to think of operator overloading as part of polymorphism, because it clearly allows "polymorphic" behavior. The properties we associate at the object level, being able to treat one object type as another, are in turn mirrored at the method level, being able to pass one type or another.
It's important to understand that polymorphism is a concept, and idea, rather than any particular programming language construct. All object oriented concepts, and computer science concepts in general, are like this. As programmers, we tend to think in terms of code rather than theory, it just makes more sense that way. It's like the difference between a problem described in words (theory) and actually seeing the numbers (program).
An "object" is just a code abstraction. It's a collection of functions and variables clumped together so mere mortals can work at a higher level without being bothered by all the details. In a sense, operator overloading is a reasonable side effect of implementing some kind of class mechanism.
Let's imagine I have plain old C and I want to add classes to it. I start with structs. What I really need to be able to do is write something like:
To do that, I need operator overloading. Once I have that, my friendly parser can take "cat.talk()" and make it into "talk(&cat)" simply. Of course, I don't need operator overloading for this, I can just pass a void pointer and worry it out at that level. But if I have it, I might as well expose it.
I tend to think of operator overloading as part of polymorphism, because it clearly allows "polymorphic" behavior. The properties we associate at the object level, being able to treat one object type as another, are in turn mirrored at the method level, being able to pass one type or another.
I think this might be one of the best explanations I've found. Good one!
Type theory is serious business! As baavgai said it's not always easy to apply theory to real code.
In my book polymorphic behavior can be seen inheritance, generics/templates, overloading and coercion.
It's pretty popular to split the term polymorphism into something called univeral or true polymorphism and something called ad-hoc polymorphism.
If you are into type theory universal polymorphism is probably more fun and included here is something called parametric polymorphism which in real life could be linked with generics in Java and templates in C++, and inclusion polymorphism which basically is inheritance.
Ad-hoc polymorphism is perhaps less about theory and more about implementation, and included here is overloading and coercion.
For me...the polymorfism is the capacity to access to the re-defined funcions(inherited of a base class) of the derived class objects through an a pointer of the type of the base class. ;-)
This post has been edited by programmer_temae: 3 May, 2009 - 08:09 PM
For me...the polymorfism is the capacity to access to the re-defined funcions(inherited of a base class) of the derived class objects through an a pointer of the type of the base class. ;-)
That is what I would think of. Being a games programmer that is the main use for polymorphism.
THe way i use polymorphism is basically to make a C++ equivalent of an interface. I would make a function that performs an operation on a resource and make an abstract base class of the resource. What function was performed would be up to the user. Example (please excuse any errors, i'm not checking my work):
My code (example.h)
cpp
#include <string> #include <vector> using namespace std;
class filter { public: virtual bool passes(string a) =0; };
vector<string> filter_strings (filter * filt, vector<string> arr) { int len = arr.length(); vector<string> retval; for (int i=0;i<len;i++) { if (filt->passes(arr.at(i))) { retval.push_back(arr.at(i)); } } return retval; }
end user's code:
cpp
#include <iostream> #include "example.h"
void print(vector<string> a) { int len = a.length(); for (int i=0;i<len;i++); cout << a[i] << endl; } }
class a_filter : public filter { public: bool passes(string a) { if (a[0]=='a') return true; else return false; } };
class b_filter : public filter { public: bool passes(string a) { if (a[0]=='b') return true; else return false; } };
int main() { vector<string> v; v.push_back("asdf"); v.push_back("qwerty"); v.push_back("bvcx"); filter * filts[2]; filts[0] = new a_filter; filts[1] = new b_filter; vector<string> result = filter_strings(filts[0], v); print(result); result = filter_strings(filts[1], v); print(result): delete filts[0]; delete filts[1]; return 0; }
Output: asdf bvcx
EDIT: in short, i agree with programmer_temae
This post has been edited by polymath: 5 May, 2009 - 01:41 PM
Polymorphism stems from the words "poly"meaning many and "morph" meaning forms. Hence I'd say inheritance ushers in function overloading which collectively form what we term polymorphism. In other words the derived class inherits that behaviour but has its own specific expression of the same- one the "many forms" of the inherited behaviour .
Forget Greek! A general, i.e. non-language specific, definition of polymorphism would be:
Polymorphism is the ability for an object reference (e.g. a pointer in c++) to refer to different types of objects during the program's execution such that when a message is sent to the object (i.e. a method is invoked on the reference), the appropriate method implementation is called.
With languages such as Smalltalk and JavaScript, polymorphism is unrestricted in the sense that a variable can refer to any type of object and any message may be sent to the object (or at least attempted). If the object does not have an implementation of the called method, the error will detected only at run time.
c++ and other strongly typed languages implement a more restrictive form of polymorphism, i.e. the compiler must be able to determine at compile time that a called method is implemented. Thus, a reference must be declared as referring to a specific type (class) of object, for example class A. Any method invoked through the reference must be known to exist at compile time (i.e. must be a method defined in or inherited by class A). Since any class that publicly inherits from A is also guaranteed to implement the method, the pointer may also refer to objects of public subclasses of A. Additionally the method must be declared virtual to insure that the methods overridden by subclasses are invoked.
Example:
CODE
class A { public: virtual void foo(); };
void bar(A *ap) { . . . ap->foo(); . . . }
Function bar might be called either with an instances of class A or an instance of a subclass that publicly inherits from A. Pointer ap can thus refer to different types of objects at different times but the right implementation of method foo will be used.