Kotlin: Override (and specify) generic interface functions - function

I want use generic interfaces that will be specified by their implementing classes, and all in all this has been working fine, like:
interface Remove <E> { fun remove(entity: E) }
class MyHandler : Remove <MyClass> {
override fun remove(entity: MyClass) { */do stuff/* }
}
However, I have a case (so far, expecting more to come) where I want the function itself to be generic. Writing the interface is no problem at all:
interface FindByID <E> { fun <K : Serializable> findByID(id: K): E }
I need K to be serializable because that's a requirement of some function I need to call.
The compiler doesn't seem to agree with my implementation attempt. When I do this:
override fun <String> findByID(id: String): User {
return someFunction(User::class.java, id) as User
}
I get two compiler errors:
overrides nothing
id is not Serializable
However, when I remove override and <String> from the signature, it works fine. This means String is serializable, which my research shows as well.
What seems to be the problem here?
Also, yes, I know that I could work around this issue in a couple of ways, like
making the interface function accept Serializable instead of <K : Serializable>
not specifying K on override, but on call (myHandler.findByID<String>("myID"))
"rerouting" the call, implementing (not overriding) in MyHandler a function that accepts Strings and then internally calls the overriden function
Although open to suggestions, I'm less interested in workarounds, but would rather like to understand and (if possible) solve the actual problem or at least know it can't be done so I can take that into account for planning

The current problem
With your current declaration of <String>, you're not specializing the type parameter as you might think. What you're actually doing is declaring a type parameter that happens to be named String (nothing to do with the well-known String type, just an unfortunate name collision). With syntax coloring, you should see that String here is in the color of a type parameter, not the same color as the String type would be. Change this name to anything else, and you'll realize the confusion.
So if we rename this to K, the problems become obvious: problem 1 "overrides nothing" is because your generic type parameter doesn't have the same : Serializable constraint as the findByID method defined in the interface. And problem 2 stems from it.
Solutions
Also, yes, I know that I could work around this issue in a couple of ways, like
not specifying K on override, but on call (myHandler.findByID("myID"))
This point is actually the essence of the issue, not a workaround: defining a generic function in your interface actually makes it part of the contract for this function to be generic.
Implementations must have a generic type parameter here.
What to do to fix it depends on what you expect to happen.
If you're ok with having generic functions in your implementations, then leave the interface as you declared it, but accept that the implementations have to deal with all possible values of K, which is most likely not what you want here.
If you want to define a specific type in your implementations, K should be part of the interface definition (not the interface method), and the method should not have a type parameter itself, but simply accept the existing K from the interface:
interface FindByID<E, K : Serializable> {
fun findByID(id: K): E
}

Related

Different ways to define a function in Kotlin

I'm new at Kotlin, migrating from Java. One thing I think is a little bit confusing is the fact we may declare a function using different ways. Bellow are at least 3 ways to accomplish that:
package me.bruno.santana
class MyClass {
fun square(number: Int) = number * number
fun square2(number: Int): Int{
return number * number
}
}
fun MyClass.square3(number: Int) = number * number
fun main(){
val obj = MyClass()
println(obj.square(3))
println(obj.square2(3))
println(obj.square3(3))
}
What is the difference between this 3 ways in practical terms? I know the last one is related to extension funcion concept, but I don't know what it differs from the conventional way in practical terms.
Another thing is weird for me is the assignment in the function definition(using equals sign to associate the function's body to the function's signature). Is it in any way different from the convetional way using curly braces as in Java?
Thank you.
1. This is single expression function:
When a function returns a single expression, the curly braces can be omitted and the body is specified after a = symbol
Explicitly declaring the return type is optional when this can be inferred by the compiler:
fun square(number: Int) = number * number
2. This is normal function
That can have single-line or multi-lines and required return type (but Unit is optional):
fun square2(number: Int): Int {
return number * number
}
3. This is Extension functions:
Kotlin provides the ability to extend a class with new functionality without having to inherit from the class or use design patterns such as Decorator.
Extensions are resolved statically: Extensions do not actually modify classes they extend. By defining an extension, you do not insert new members into a class, but merely make new functions callable with the dot-notation on variables of this type
Often used to write utility functions and enhance readability via dot-notation.
If an extension is declared outside its receiver type, such an extension cannot access the receiver's private members.
fun MyClass.square3(number: Int) = number * number
To add something about extension functions: there are four common reasons to use them that I can think of.
You don't control the source code of the class you're adding the function to.
You want to add functions only to specifically typed instances of a class. For example, you could write a function for your Foo<T: Animal> class that is only available on instances that are a Foo<Pet>.
You want to add something like a final function to an interface. This is used frequently in the standard library. If you define a function inside an interface, its behavior is unpredictable because interface functions cannot be final. By declaring it outside the interface as an extension, it can be hidden (by writing a different extension function with the same signature), but it cannot be overridden. Hiding it still requires the user to import the other version of the function, so it must be done explicitly.
You want to confine the scope of the added function. Maybe the function only really makes sense in a certain context, so you don't want it to clutter the IDE auto-complete everywhere. Or maybe it uses a property of a certain class, so it must be defined within that class.
When you're just composing one of your own typical classes, you won't frequently need to use an extension function.

Is there a language allowing dynamic binding for arguments?

Is there a language allowing a supertype A defining a method useFoo (Foo foo) such as B, derivated from A defining a method useFoo(Bar bar), (Bar is derivated from Foo), when using B as a A with a Foo that is a Bar, it will run the most specialised version of useFoo ?
Java example (not working, unfortunately) :
public class Foo {
}
public class Bar extends Foo {
}
public class A {
void useFoo (Foo foo) {
System.out.println("A");
}
}
public class B extends A {
void useFoo (Bar bar) {
System.out.println("B");
}
}
public static void main(String[] args) {
A b = new B();
b.useFoo(new Bar()); // actually returns "A", is there one returning "B" ?
}
I know there is a way to make this happen with a "few" lines (using a visitor for instance) but I would like to know if any (compiled) language would allow it.
I admit I would like to know if this is even possible, the contrary would not surprise me, and what prevents it ?
Is there a better name for this concept ?
Edit : In java, it is named Contravariance. thank you #Kevinrob
Your question is related to the following notions:
Covariance: an argument may be redefined in subclasses to be a subclass of the original argument class. This convention is used in Eiffel, for example. The approach is known to lead to type safety issues, CAT-calls (CAT = Changing Availability or Type), that need to be addressed in a special way to preserve type system soundness. The strong argument for covarince is that it combines nicely with contracts (e.g., with Design by Contract).
Multiple dispatch: method calls are performed by relying not only on type a target of a call, but also on types of arguments. The page lists several languages that support this mechanism. Multiple dispatch is a way to deal with covariance and contravariance. However one has to be careful when designing sets of methods that rely on the mechanism to avoid executing an unexpected method at run-time.
Generic programming: instead of fixing argument types by the suppliers, they can be fixed by the clients. The mechanism is type safe and is free from the issues of the preceding two, but it requires actual generic parameters to be explicitly specified by the clients and if there are too many such arguments the type declarations may become unwieldy. Nowadays there are a lot of languages that support it.

Does Swift have dynamic dispatch and virtual methods?

Coming form a C++/Java/C# background I was expecting to see virtual methods in Swift, however reading the swift documentation I see no mention of virtual methods.
What am I missing?
Due to large number of views, I have decided to offer a reward for an upto date and very clear/detail answer.
Unlike C++, it is not necessary to designate that a method is virtual in Swift. The compiler will work out which of the following to use:
(the performance metrics of course depend on hardware)
Inline the method : 0 ns
Static dispatch: < 1.1ns
Virtual dispatch 1.1ns (like Java, C# or C++ when designated).
Dynamic Dispatch 4.9ns (like Objective-C).
Objective-C of course always uses the latter. The 4.9ns overhead is not usually a problem as this would represent a small fraction of the overall method execution time. However, where necessary developers could seamlessly fall-back to C or C++. In Swift, however the compiler will analyze which of the fastest can be used and try to decide on your behalf, favoring inline, static and virtual but retaining messaging for Objective-C interoperability. Its possible to mark a method with dynamic to encourage messaging.
One side-effect of this, is that some of the powerful features afforded by dynamic dispatch may not be available, where as this could previously have been assumed to be the case for any Objective-C method. Dynamic dispatch is used for method interception, which is in turn used by:
Cocoa-style property observers.
CoreData model object instrumentation.
Aspect Oriented Programming
The kinds of features above are those afforded by a late binding language. Note that while Java uses vtable dispatch for method invocation, its still considered a late binding language, and therefore capable of the above features by virtue of having a virtual machine and class loader system, which is another approach to providing run-time instrumentation. "Pure" Swift (without Objective-C interop) is like C++ in that being a direct-to-executable compiled language with static dispatch, then these dynamic features are not possible at runtime. In the tradition of ARC, we might see more of these kinds of features moving to compile time, which gives an edge with regards to "performance per watt" - an important consideration in mobile computing.
All methods are virtual; however you need to declare that you are overriding a method from a base class using the override keyword:
From the Swift Programming Guide:
Overriding
A subclass can provide its own custom implementation of an instance
method, class method, instance property, or subscript that it would
otherwise inherit from a superclass. This is known as overriding.
To override a characteristic that would otherwise be inherited, you
prefix your overriding definition with the override keyword. Doing so
clarifies that you intend to provide an override and have not provided
a matching definition by mistake. Overriding by accident can cause
unexpected behavior, and any overrides without the override keyword
are diagnosed as an error when your code is compiled.
The override keyword also prompts the Swift compiler to check that
your overriding class’s superclass (or one of its parents) has a
declaration that matches the one you provided for the override. This
check ensures that your overriding definition is correct.
class A {
func visit(target: Target) {
target.method(self);
}
}
class B: A {}
class C: A {
override func visit(target: Target) {
target.method(self);
}
}
class Target {
func method(argument: A) {
println("A");
}
func method(argument: B) {
println("B");
}
func method(argument: C) {
println("C");
}
}
let t = Target();
let a: A = A();
let ab: A = B();
let b: B = B();
let ac: A = C();
let c: C = C();
a.visit(t);
ab.visit(t);
b.visit(t);
ac.visit(t);
c.visit(t);
Note the self reference in the visit() of A and C. Just like in Java it gets not copied over but instead self keeps the same type until it is used in an override again.
The result is A, A, A, C, C so there's no dynamic dispatch available. Unfortunately.
As of Xcode 8.x.x and 9 Beta, virtual methods in C++ might be translated in Swift 3 and 4 like this:
protocol Animal: AnyObject { // as a base class in C++; class-only protocol in Swift
func hello()
}
extension Animal { // implementations of the base class
func hello() {
print("Zzz..")
}
}
class Dog: Animal { // derived class with a virtual function in C++
func hello() {
print("Bark!")
}
}
class Cat: Animal { // another derived class with a virtual function in C++
func hello() {
print("Meow!")
}
}
class Snoopy: Animal { // another derived class with no such a function
//
}
Give it a try.
func test_A() {
let array = [Dog(), Cat(), Snoopy()] as [Animal]
array.forEach() {
$0.hello()
}
// Bark!
// Meow!
// Zzz..
}
func sayHello<T: Animal>(_ x: T) {
x.hello()
}
func test_B() {
sayHello(Dog())
sayHello(Cat())
sayHello(Snoopy())
// Bark!
// Meow!
// Zzz..
}
In sum, the similar things we do in C++ can be achieved with Protocol and Generic in Swift, I think.
I also came from C++ world and faced the same question. The above seems to work, but it looks like a C++ way, not somewhat Swifty way, though.
Any further suggestions will be welcome!
Let’s begin by defining dynamic dispatch.
Dynamic dispatch is considered a prime characteristic of object-oriented languages.
It is the process of selecting which implementation of a polymorphic operation (method/function) to call at run time, according to Wikipedia.
I emhasized run time for a reason since this is what differentiates it from static dispatch. With static dispatch, a call to a method is resolved at compile time. In C++, this is the default form of dispatch. For dynamic dispatch, the method must be declared as virtual.
Now let’s examine what a virtual function is and how it behaves in the context of C++
In C++, a virtual function is a member function which is declared within a base class and is overriden by a derived class.
Its main feature is that if we have a function declared as virtual in the base class, and the same function defined in the derived class, the function in the derived class is invoked for objects of the derived class, even if it is called using a reference to the base class.
Consider this example, taken from here:
class Animal
{
public:
virtual void eat() { std::cout << "I'm eating generic food."; }
};
class Cat : public Animal
{
public:
void eat() { std::cout << "I'm eating a rat."; }
};
If we call eat() on a Cat object, but we use a pointer to Animal, the output will be “I’m eating a rat.”
Now we can study how this all plays out in Swift.
We have four dispatch types, which are the following (from fastest to slowest):
Inline dispatch
Static dispatch
Virtual dispatch
Dynamic dispatch
Let's take a closer look at dynamic dispatch. As a preliminary, you have to know about the difference between value and reference types. To keep this answer at a reasonable length, let’s just say that if an instance is a value type, it keeps a unique copy of its data. If it’s a reference type, it shares a single copy of the data with all other instances.
Static dispatch is supported by both value and reference types.
For dynamic dispatch, however, you need a reference type. The reason for this is that for dynamic dispatch you need inheritance, and for inheritance, which value types do not support, you need reference types.
How to achieve dynamic dispatch in Swift? There are two ways to do it.
The first is to use inheritance: subclass a base class and then override a method of the base class. Our previous C++ example looks something like this in Swift:
class Animal {
init() {
print("Animal created.")
}
func eat() {
print("I'm eating generic food.")
}
}
class Cat: Animal {
override init() {
print("Cat created.")
}
override func eat() {
print("I'm eating a rat.")
}
}
If you now run the following code:
let cat = Cat()
cat.eat()
The console output will be:
Cat created.
Animal created.
I'm eating a rat.
As you can see, there is no need to mark the base class method as virtual, the compiler will automatically decide which dispatch option to use.
The second way to achieve dynamic dispatch is to use the dynamic keyword along with the #objc prefix. We need #objc to expose our method to the Objective-C runtime, which relies solely on dynamic dispatch. Swift, however, only uses it if it has no other choice. If the compiler can decide at compile time which implementation to use, it opts out of dynamic dispatch. We might use #objc dynamic for Key-Value Observing or method swizzling, both of which are outside the scope of this answer.
Swift was made to be easy to learn for Objective-C programmers, and in Objective-C there are no virtual methods, at least not in the way that you might think of them. If you look for instruction on how to create an abstract class or virtual method in Objective-C here on SO, usually it's a normal method that just throws an exception and crashes the app. (Which kinda makes sense, because you're not supposed to call a virtual method)
Therefore if Swift documentation says nothing about virtual methods, my guess is that, just as in Objective-C, there are none.

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.

Try to describe polymorphism as easy as you can [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
How can polymorphism be described in an easy-to-understand way?
We can find a lot of information about the subject on the Internet and books, like in Type polymorphism. But let's try to make it as simple as we can.
Two objects respond to the same message with different behaviors; the sender doesn't have to care.
Every Can with a simple pop lid opens the same way.
As a human, you know that you can Open() any such can you find.
When opened, not all cans behave the same way. Some contain nuts, some contain fake snakes that pop out. The result depends on what TYPE of can, if the can was a "CanOfNuts" or a "CanOfSnakes", but this has no bearing on HOW you open it. You just know that you may open any Can, and will get some sort of result that is decided based on what type of Can it was that you opened.
pUnlabledCan->Open(); //might give nuts, might give snakes. We don't know till we call it
Open() has a generic return type of "Contents" (or we might decide no return type), so that open always has the same function signature.
You, the human, are the user/caller.
Open() is the virtual/polymorphic function.
"Can" is the abstract base class.
CanOfNuts and CanOfSnakes are the polymorphic children of the "Can" class.
Every Can may be opened, but what specifically it does and what specific tye of contents it returns are defined by what sort of can it is.
All that you know when you see pUnlabledCan is that you may Open() it, and it will return the contents. Any other behaviors (such as popping snakes in your face) are decided by the specific Can.
This is from my answer from a similiar question. Here's an example of polymorphism in pseudo-C#/Java:
class Animal
{
abstract string MakeNoise ();
}
class Cat : Animal {
string MakeNoise () {
return "Meow";
}
}
class Dog : Animal {
string MakeNoise () {
return "Bark";
}
}
Main () {
Animal animal = Zoo.GetAnimal ();
Console.WriteLine (animal.MakeNoise ());
}
The Main() method doesn't know the type of the animal and depends on a particular implementation's behavior of the MakeNoise() method.
The simplest description of polymorphism is that it is a way to reduce if/switch statements.
It also has the benefit of allowing you to extend your if/switch statements (or other people's ones) without modifying existing classes.
For example consider the Stream class in .NET. Without polymorphism it would be a single massive class where each method implements a switch statement something like:
public class Stream
{
public int Read(byte[] buffer, int offset, int count)
{
if (this.mode == "file")
{
// behave like a file stream
}
else if (this.mode == "network")
{
// behave like a network stream
}
else // etc.
}
}
Instead we allow the runtime to do the switching for us in a more efficient way, by automatically choosing the implementation based on the concrete type (FileStream, NetworkStream), e.g.
public class FileStream : Stream
{
public override int Read(byte[] buffer, int offset, int count)
{
// behave like a file stream
}
}
public class NetworkStream : Stream
{
public override int Read(byte[] buffer, int offset, int count)
{
// behave like a network stream
}
}
Poly: many
Morphism: forms / shapes
The Actor vs. the Character (or Role)
Apples and oranges are both fruit. Fruit can be eaten. Hence, both apples and oranges can be eaten.
The kicker? You eat them differently! You peel the oranges, but not the apples.
So the implementation differs, but the end result is the same, you eat the fruit.
If it walks like a duck and quacks like a duck, then you can treat it as a duck anywhere you need a duck.
This is a better article actually
Polymorphism allows Objects to "Look" the same, but behave in different ways. The usual example is to take an animal base class with a Speak() Method, A dog subclass would emit a Bark whereas a Pig subclass would emit an oink.
The 5 second short answer most people use so other developers can get their head around Polymorphism is overloading and overriding
Same syntax, different semantics.
Simplest way to describe it: a verb that can apply to more than one kind of object.
Everything else, as Hillel said, is just commentary.
Polymorphism is treating things abstractly by relying on knowledge of a common "parent" (think heirarchies like Animal as a parent of Dogs and Cats).
For example, all Animals can breathe oxygen, and while they may each do this differently you could design a facility that provides oxygen for Animals to breathe, supporting both Dogs and Cats.
As a little extra, you can do this even though Animal is an "abstract" identifier (there is no real "Animal" thing, just types of Animals).
Polymorphism is the storing of values of more than one type in a location of a single type.
Note that most of the other answers to this question, at the time of my writing, are actually describing dynamic dispatch, not polymorphism.
Dynamic dispatch requires polymorphism, but the reverse is not true. One could imagine a language very similar to Java or C# but whose System.Object had no members; typecasting would be necessary before doing anything with the value. In this notional language, there would be polymorphism, but not necessarily virtual methods, or any other dynamic dispatch mechanisms.
Dynamic dispatch is the related but distinct concept, well enough described in most of the other answers. However, the way it normally works in object-oriented languages (selecting a function based on the first ('this' or 'Self') argument type) is not the only way it can work. Multiple dispatch is also possible, where the selection is applied across the types of all the arguments.
Similarly, overload resolution and multiple dispatch are exact analogues of one another; overload resolution is multiple dispatch applied to static types, while multiple dispatch is overload resolution applied to runtime types stored in polymorphic locations.
Polymorphism is dividing the world into boxes based on common properties and treating the items in a given box as interchangeable when you only want to use these common properties.
Polymorphism is the ability to treat different things as if they were the same thing by establishing a shared identity between them then exploiting it.
Polymorphism is what you get when the same method applies to multiple classes. For example, both a String and a List might have "Reverse" methods. Both methods have the same name ("Reverse"). Both methods do something very similar (reverse all the characters or reverse the order of the elements in the list). But the implementation of each "Reverse" method is different and specific to its class. (In other words, the String reverses itself like a string, and the List reverses itself like a list.)
To use a metaphor, you could say "Make Dinner" to a French chef or to a Japanese chef. Each would perform "make dinner" in their own characteristic way.
The practical result is that you could create a "Reversing Engine" that accepts an object and calls "Reverse" on it. As long as the object has a Reverse method, your Reversing Engine will work.
To extend the chef analogy, you could build a "Waiterbot" that tells chefs to "Make Dinner". The Waiterbot doesn't have to know what type of dinner is going to be made. It doesn't even have to make sure it's talking to a chef. All that matters is that the "chef" (or fireman, or vending machine, or pet food dispenser) knows what to do when it's told to "Make Dinner".
What this buys you as a programmer is fewer lines of code and either type-safety or late binding. For example here's an example with type safety and early binding (in a c-like language that I'm making up as I go):
class BankAccount {
void SubtractMonthlyFee
}
class CheckingAccount : BankAccount {}
class SavingsAccount : BankAccount {}
AssessFee(BankAccount acct) {
// This will work for any class derived from
// BankAccount; even classes that don't exist yet
acct.SubtractMonthlyFee
}
main() {
CheckingAccount chkAcct;
SavingsAccount saveAcct;
// both lines will compile, because both accounts
// derive from "BankAccount". If you try to pass in
// an object that doesn't, it won't compile, EVEN
// if the object has a "SubtractMonthlyFee" method.
AssessFee(chkAcct);
AssessFee(saveAcct);
}
Here's an example with no type safety but with late binding:
class DatabaseConnection {
void ReleaseResources
}
class FileHandle {
void ReleaseResources
}
FreeMemory(Object obj) {
// This will work for any class that has a
// "ReleaseResources" method (assuming all
// classes are ultimately derived from Object.
obj.ReleaseResources
}
main() {
DatabaseConnection dbConn;
FileHandle fh;
// You can pass in anything at all and it will
// compile just fine. But if you pass in an
// object that doesn't have a "ReleaseResources"
// method you'll get a run-time error.
FreeMemory(dbConn);
FreeMemory(fh);
FreeMemory(acct); //FAIL! (but not until run-time)
}
For an excellent example, look at the .NET ToString() method. All classes have it because all classes are derived from the Object class. But each class can implement ToString() in a way that makes sense for itself.
EDIT: Simple != short, IMHO
Polymorphism is language functionality allowing high-level algorithmic code to operate unchanged on multiple types of data.
This is done by ensuring the operations invoke the right implementation for each data type. Even in an OOP context (as per this question's tag), this "right implementation" may be resolved at compile-time or run-time (if your language supports both). In some languages like C++, compiler-supplied support for run-time polymorphism (i.e. virtual dispatch) is specific to OOP, whereas other types of polymorphism can also operate on data types that aren't objects (i.e. not struct or class instances, but may be builtin types like int or double).
( The types of polymorphism C++ supports are listed and contrasted in my answer: Polymorphism in c++ - even if you program other languages, it's potentially instructive )
The way I try and think of it is something that looks the same but can have different functionality depending on the instance. So you can have a type
interface IJobLoader
but depending on how it is used can have different functionality while still looking the same. You may have instances for BatchJobLoader, NightlyJobLoader etc
Maybe I am way off.
The term polymorphism can also apply to overloading functions. For example,
string MyFunc(ClassA anA);
string MyFunc(ClassB aB);
is a non-object oriented example of polymorphism.
Is the ability that objects have to respond to the same message in different ways.
For instance , in languages such as smalltalk, Ruby, Objective-C, you just have to send the message and they will respond.
dao = XmlDao.createNewInstance() #obj 1
dao.save( data )
dao = RdbDao.createNewnewInstance() #obj 2
dao.save( data )
In this example two different objects, responded in different ways to the same messages: "createNewInstance() and save( obj )"
They act in different ways, to the same message. In the above languages, the classes might not even be in the same class hierarchy, it is enough that they respond to the message.
In languages such as Java, C++, C# etc. In order to assign the object to an object reference, they must share the same type hierarchy either by implementing the interface or by being subclass of a common class.
easy .. and simple.
Polymorphism is by far, the most important and relevant feature of object oriented programming.
It is a way to treat different things that can do something something similar in the same way without caring how they do it.
Let's say you have a game with a bunch of different types of Vehicles driving around such as Car, Truck, Skateboard, Airplane, etc... They all can Stop, but each Vehicle stops in a different way. Some Vehicles may need to shift down gears, and some may be able to come to a cold stop. Polymophism lets you do this
foreach (Vehicle v in Game.Vehicles)
{
v.Stop();
}
The way that stop is implemented is deferred to the different Vehicles so your program doesn't have to care about it.
It's just a way to get old cold to call new code. You write some application that accepts some "Shape" interface with methods that others must implement (example - getArea). If someone comes up with a new whiz-bang way to implement that interface your old code can call that new code via the the getArea method.
The ability of an object of some type (e.g. a car) to act (e.g. brake) like one of another type (e.g. a vehicle) which usually suggests common ancestry (e.g. car is a subtype of vehicle) at one point in the type hierarchy.
Polymorphism is the Object Oriented solution to problem of passing a function to another function. In C you can do
void h() { float x=3.0; printf("%f", x); }
void k() { int y=5; printf("%i", y); }
void g(void (*f)()) { f(); }
g(h); // output 3.0
g(k); // output 5
In C things get complicated if the function depends on additional parameters. If the functions h and k depend on different types of parameters you are in trouble and you must use casting. You have to store those parameters in a data structure, and pass a pointer to that data structure to g which passes it to h or k. h and k cast the pointer into a pointer to the proper structure and unpack the data. Very messy and very unsafe because of possible casting errors:
void h(void *a) { float* x=(float*)a; printf("%f",*x); }
void k(void *a) { int* y=(int*)a; printf("%i",*y); }
void g(void (*f)(void *a),void *a) { f(a); }
float x=3.0;
int y=5;
g(h,&x); // output x
g(k,&y); // output y
So they invented polymorphism. h and k are promoted to classes and the actual functions to methods, the parameters are member variables of the respective class, h or k. Instead of passing the function around, you pass an instance of the class that contains the function you want. The instance contains its own parameters.
class Base { virtual public void call()=0; }
class H : public Base { float x; public void call() { printf("%f",x);} } h;
class K : public Base { int y; public void call() { printf("%i",y);} } k;
void g(Base &f) { f.call(); };
h.x=3.0;
k.y=5;
g(h); // output h.x
g(k); // output k.x