Is there a language allowing dynamic binding for arguments? - language-agnostic

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.

Related

Kotlin: Override (and specify) generic interface functions

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
}

Is a function that depends on public class members can be considered pure

After a stumbled upon this question I thought about how I would define a pure function. I have two rules to accept a function as pure which somewhat differ from the definition cited in the top answer. I'm interested to know if my view is correct or not.
My "2 rules" are:
The function will not change the state of the program.
The input is constant for the same arguments or the same local public program state.
To clarify the second point, by local public state I mostly mean public class members. Local means that the state is strongly associated with the function and is exclusive to it (ie. not some global variables).
My reasoning for using that definition is that it is just a more expanded view (perhaps too specific to CS) on the term arguments, as I see local public state being only a different interface for passing function arguments.
Is this definition acceptable or is the inclusion of a class context destroys the "prunes" of the function?
Edit: As an example for what I mean consider the following class (C++).
class Foo
{
public:
int Number;
int foo(int v) { return Number + v; }
}
Considering that an instance function call is actually the following call:
foo(&this, 123)
How is this different from passing the public data (Number) via a struct?
struct Foo
{
int Number;
}
foo(Foo { 1 }, 123);
No, that "or the same local public program state" is not in the pure method definition everyone else agrees with.
A pure function computes a value based on the input parameters and the input parameters alone, and does not, beyond returning the computed value, produce any observable side effects.
I advice you to take a look at the Wikipedia page on Pure function as it shows some examples.
--
Also note that "no observable side effects" does not mean "no side effects whatsoever", but the gray area overlapping those two generally only include runtime-specific side effects that you have no control over and generally do not observe.
This also includes state such as "there is enough memory to allocate the memory needed".

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.

Interface explosion problem

I am implementing a screen using MVP pattern, with more feature added to the screen, I am adding more and more methods to the IScreen/IPresenter interface, hence, the IScreen/IPresenter interface is becoming bigger and bigger, what should I do to cope with this situation?
There is no specific limit on the number of artifacts (methods, constants, enumerations, etc) - say N - in an interface such that we can say if interface X has more than N artifacts, it is bloated.
At least not without a context. In this case, the context is what is the interface supposed to provide?, or better yet, what are implementations of this interface supposed to do? What is the intended behavior or role of classes implementing the interface?
I would strongly suggest you get familiar with certain metrics like cohesion and coupling (both in general and in specifics to OO.) In particular, I'd suggest you take a look at LCOM. Once you understand it, it will help you eyeball situations like the one you are encountering now.
http://javaboutique.internet.com/tutorials/coupcoh/
One of the last things you want to do with an interface or class (or even package or module if you were doing procedural programming) is to turn them into bags of methods and functions where you throw everything but the kitchen sink. That leads to either poorly cohesion or tight coupling (or both.)
One of the problems with interfaces is that we cannot easily compute or estimate their LCOM as one would with actual classes, which could guide you in deciding when to r-efactor. So for that you have to use a bit of intuition.
Let's assume your interface is named A for the sake of argument. Then,
Step 1:
Consider grouping the interface methods by arguments: is there a subset of methods that operate on the same type of arguments? If so, are they significantly different from other method groups?
interface A
{
void method1();
void method2(someArgType x);
someOtherType y method3();
...
void doSomethingOn( someType t );
boolean isUnderSomeCondition( someType t )
someType replaceAndGetPrev( someType t, someFields ... )
}
In such a case, consider splitting that group into its own interface, B.
Step 2:
Once you extract interface B, does it look like this?
interface B
{
void doSomethingOn( someType t );
...
boolean isUnderSomeCondition( someType t )
...
someType replaceAndGetPrev( someType t, someFields ... )
}
That is, it represents methods that do things on some type?
If so, your interface is mimicking a procedural module operation on an ADT (in this case, someType) - nothing wrong with if you are using a procedural or multi-paradigm language.
Within reason and while being pragmatic, in OO, you minimize procedures that do things on other objects. You call methods in those objects to do things to themselves on your behalf. Or more precisely, you signal them to do something internally.
In such a case, consider turning B into a class encapsulating the type (and, have it extend an interface with the same signature, but only if it makes sense, if you expect different implementations of artifacts encapsulating/managing elements of that type.)
class Bclass
{
someType t;
Bclass(){ t=new someType();}
...
void doSomethingOn();
...
boolean isUnderSomeCondition()
...
someType replaceAndGetPrev( someFields ... )
}
Step 3:
Determine the relationships between the interfaces and classes re-factored out from A.
If B represent things that can only exist when A does (A is a context for B, for example a servlet request exists in a servlet context in Java EE lingo), then have B define a method that returns A (for example A B.getContext() or something like that.)
If B represent things that are managed by A (A being a composite of things, including B), then have A define a method that returns B (B A.getBThingie())
If there is no such relationship between A and B, and they have nothing in common other than they were grouped together, then chances are that the original interface was poorly cohesive.
If you cannot disentangle one from the other without breaking a significant amount of your design, then that's a sign that pieces of your system had poor boundaries and are tightly coupled.
Hope it helps.
ps. Also, I would also avoid trying to fit your interfaces and classes into traditional patterns UNLESS doing so serves an application/business specific purpose. I gotta throw that in there just in case. Too many people run amok with the GoF book trying to fit their classes into patterns rather than asking 'what problem am I solving with this?'
In my opinion, a "perfect program world" contains public interfaces and internal implementations.
Each interface is strictly "in charge" of one thing only.
I try to view these entities is "little" human beings which interact with one another in order to complete a certain task.
(sorry if this is a bit of philosophizing)
What flavor of Model-View-Presenter are you using? I've found that Passive View rarely involves overlap between the view and presenter interfaces - normally they change at different times.
Typically the view's interface is essentially a view model, perhaps something like this (C#-style):
public interface IEditCustomerView {
string FirstName { get; set; }
string LastName { get; set; }
string Country { get; set; }
List<Country> AvailableCountries { get; set; }
// etc.
}
The view implementation usually has handlers for user gestures that are usually thin wrappers that call into the presenter:
public class EditCustomerView {
// The save button's 'click' observer
protected void SaveCustomer() {
this.presenter.SaveCustomer();
}
}
The presenter generally has a method for each user gesture, but none of the data, since it gets that directly from the view (which is generally passed to the presenter in the constructor, though you can pass it on each method call if it's more suitable):
public interface IEditCustomerPresenter {
void Load();
void SaveCustomer();
}
Can you break your interface into sub-interfaces representing sections of the screen? For example, if your screen is divided into groups such as a navigation section, or a form section, or a toolbar section, then your IPresenter/IScreen could have getters for interfaces for those sections, and those sections could contain relevant methods for each section. Your main IPresenter/IScreen would still have methods that are relevant to the whole interface.
If sections of the screen don't work as a logical category for your application, think of other things that might provide a logical breakdown. Workflow would be one.
EDIT For example:
For example, for a large UI which I did, I actually broke up not just my presenter but also my model and view code. The entire screen neatly broke up into a tree (in this case), with the main presenter delegating work to the children presenters and down the chain. When I had to later go back and add to this UI, I found fitting into the hierarchy fairly simple and maintainable.
In an example that works like this, the MainPresenter implementation of IMainPresenter knows about both it's model, it's view, and it's sub-presenters. Each SubPresenter controls its own view and model. Any operations on what logically belongs in that sub-section should be in the SubPresenter. If your screen is laid out in such a way that there are logical units like this, such a set-up should work well. Each SubPresenter should be able to return its SubView for the MainPresenter to plug into the MainView as appropriate.

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