Is all dynamic binding considered to be polymorphism? Specifically, I'm talking about Java. If not, please explain both terms.
What I know: not all inheritance is polymorphism but inheritance is used in all polymorphism.
First of all dynamic binding (or late binding) is an improper term. You are talking about dynamic dispatch which is a different thing.
Dynamic binding is choosing which implementation of a method will be called at runtime, but this doesn't happen in Java. But you have dynamic dispatch which is the ability to choose the correct polymorphic implementation of a method at compile time (which usually translates to choosing the most specialized version of the method/function).
But I wouldn't say that dynamic dispatch is polymorphism, I'd say that to support polymorphism you need a mechanism to choose the correct implementation of a method and this is dynamic dispatch.
Inheritance is a kind of polymorphism called subtyping (or subtype polymorphism) so, contrary to what you say, inheritance is always a form of polymorphism, but other kinds of polymorphism exist, think about:
ad hoc polymorphism (implemented through overloading) where the same function has different meanings when applied to different arguments
parametric polymorphism (implemented with Generics in Java) where you have types with type variables so that a single type can express infinite number of types by binding the variable to a specific type (or a class of types), think about List<Integer>
If the method call is decided at runtime- it is dynamic polymorphism. If the method call is decided by compiler during compile time it is called static polymorphism.
Example:
public static void eat (Veg vegetable) {
System.out.println("I am vegetarian");
}
public static void eat(Meat meat) {
System.out.println("I am non-vegetarian");
}
//if your main is this way
public static void main(String args[])
{
Veg v = new Meat();
callEat(v);
}
It prints "I am vegetarian" . This is decided by compiler on runtime. Its also called as method overriding.
int add (int a , int b){
return a+b;
}
int add(int a, int b, int c){
return a+b+c;
}
void main (){
add(1,2);
add(1,2,3);
}
Here the function is choosen depending on the parameter passed even when the name and return type of the method is the same. This is done at compile time. This is static polymorphism. It is also called as method overriding.
Related
There are too many associated names: Early and Late Binding, Static and Dynamic Dispatch, Runtime vs. Compile-time Polymorphism, etc. that I don't understand the difference.
I found a clear explanation, but is it correct? I'll paraphrase JustinC:
Binding: is determining the type of a variable (object?). If it's done at compile time, its early binding. If it's done at run time, it's late binding.
Dispatch: is determining which method matches the method call. Static Dispatch is computing methods at compile time, whereas dynamic dispatch is doing it at run time.
Is Binding matching up primitive and reference variables with primitive values and objects respectively?
Edit: Please give me some clear reference material so I can read more about this.
I believe the confusion typically comes from how overloaded these terms are.
We program our programs in a high level language, and either a compiler or an interpreter must transform that into something a machine actually understands.
In coarse terms, you can picture a compiler transforming our method code into some form of machine code. If the compiler knew at that point exactly where in the memory that method would reside when we run our program later, then it could safely go and find every method invocation of this compiled method and replace it with a jump to this address where the compiled code resides, right?.
Well, materializing this relationship is what I understand as binding. This binding, though, could happen at different moments, for example at compile time, linking time, load time, or at run time depending on the design of the language.
The terms static and dynamic are generally used to refer to things bound before run time and at run time, respectively.
Later binding times are associated with greater flexibility, earlier binding times are associated with greater efficiency. Language designers have to balance these two aspects when they're creating a language.
Most object-oriented programming languages support subtype polymorphism. In these languages, virtual methods are bound at runtime depending on the dynamic type of the object at that point. In other words, virtual method invocations are dispatched to the appropriate implementation at runtime based on the dynamic type of the object implementation involved and not based solely on its static type reference.
So, in my opinion, you must first bind the method invocation to a specific implementation or execution address, and then you can dispatch an invocation to it.
I had answered a very similar question in the past in which I demonstrate with examples how this happens in Java.
I would also recommend reading the book Programming Language Pragmatics. It is a great reference to learn all this kind of stuff from a theoretical standpoint.
When you're looking for "low level" definitions, probably the only legitimate source is our old friend - the JLS. Though it does not give a clear definition in this case, the context in which it uses each term might be enough.
Dispatch
This term is indeed mentioned in procedures of determining which method to call.
15.12.2. Compile-Time Step 2: Determine Method Signature
The second step searches the type determined in the previous step for
member methods. This step uses the name of the method and the argument
expressions to locate methods that are both accessible and applicable,
that is, declarations that can be correctly invoked on the given
arguments.
There may be more than one such method, in which case the
most specific one is chosen. The descriptor (signature plus return
type) of the most specific method is the one used at run time to
perform the method dispatch. A method is applicable if it is
applicable by one of strict invocation
The elaboration on what is the "most specific" method is done in 15.12.2.5 Choosing the Most Specific Method.
As for "dynamic dispatch",
JLS 12.5. Creation of New Class Instances:
Unlike C++, the Java programming language does not specify altered
rules for method dispatch during the creation of a new class instance.
If methods are invoked that are overridden in subclasses in the object
being initialized, then these overriding methods are used, even before
the new object is completely initialized.
It includes
Example 12.5-2. Dynamic Dispatch During Instance Creation
class Super {
Super() {
printThree();
}
void printThree() {
System.out.println("three");
}
}
class Test extends Super {
int three = 3;
void printThree() {
System.out.println(three);
}
public static void main(String[] args) {
Test t = new Test();
t.printThree();
}
}
Output:
0
3
This happens because during the constructor call chain, Super's constructor calls printThree, but due to dynamic dispatch the method in Test is called, and that is before the field is initialized.
Binding
This term is used in contexts of class member access.
Example 15.11.1-1. Static Binding for Field Access demonstrates early and late bindings. I will summarize the examples given there for the lazy of us:
class S {
int x = 0;
int z() { return x; }
}
class T extends S {
int x = 1;
int z() { return x; }
}
public class Test1 {
public static void main(String[] args) {
S s = new T();
System.out.println("s.x=" + s.x);
System.out.println("s.x=" + s.z());
}
}
Output:
s.x=0
s.x=1
Showing that the field uses "early binding", while the instance method uses "late binding":
This lack of dynamic lookup for field accesses allows programs to be run efficiently with
straightforward implementations. The power of late binding and overriding is available, but
only when instance methods are used.
Binding is also used in regards to determining the type of a generic,
8. Classes
Classes may be generic (§8.1.2), that is, they may declare type variables whose bindings may differ among different instances of the class.
Meaning that if you create 2 instances of List<String>, the bindings of String in both instances are different from each other.
This also applies to raw types:
4.8. Raw Types
class Outer<T>{
T t;
class Inner {
T setOuterT(T t1) { t = t1; return t; }
}
}
The type of the member(s) of Inner depends on the type parameter of Outer. If Outer is raw, Inner must be treated as raw as well, as there is no valid binding for T.
Meaning that declaring Outer outer (this will generate a raw type warning) does not allow to determine the type of T (obviously - it wasn't defined in the declaration).
These are general terms, you can summarize it in this way: when some thing(method or object) is static/early it means that thing is configured in compile-time and there is no ambiguity in run time for example in the following code:
class A {
void methodX() {
System.out.print("i am A");
}
}
If we create an instance of A and call methodX(), nothing is ambitious and everythin is configured at compile time but if we have the following code
class B extends A {
void methodX() {
System.out.print("i am B");
}
}
....
A objX= new B();
objX.methodX();
Out put of method x is not known until runtime, so this method is dynamically binded/dispatched (we can use the term dispatched instead of bind for methods link).
Recently My teacher was teaching Polymorphism and he taught that there are two aspects in Polymorphism as
Run-time Polymorphism
Compile-time Polymorphism
And then He showed us this code
class A {
void ab(){
System.out.println("ab() in class A");
}
}
class B extends A {
void ab(){
System.out.println("ab() in class B");
}
}
class ObCo {
public static void main(String args[]){
A a1 = new B();
a1.ab();
}
}
The output is ab() in class B
And when I try the following code,
class A {
int i = 10;
}
class B extends A {
int i = 100;
}
class ObCo {
public static void main(String args[]){
A a1 = new B();
System.out.println(a1.i);
}
}
According to the previous code, the output should be 100 But the output is 10 Which rises up these questions in my mind.
Is Polymorphism a concept only related to Overriding methods?
Is the first code block relevant to Polymorphism?
If yes, what is run-time Polymorphism and compile-time Polymorphism?
If no, please give me an example where Polymorphism is seen.
Detailed answers on those questions will be highly appreciated.
Polymorphism applies to non-static non-final methods only. The code you tried is not polymorphism but field hiding (emphasis mine):
Within a class, a field that has the same name as a field in the superclass hides the superclass's field, even if their types are different. Within the subclass, the field in the superclass cannot be referenced by its simple name. Instead, the field must be accessed through super, which is covered in the next section. Generally speaking, we don't recommend hiding fields as it makes code difficult to read.
With this in mind, answers to your questions:
Is Polymorphism a concept only related to Overriding methods?
Yes.
Is the first code block is relevant to Polymorphism?
Yes.
If yes, What is run-time Polymorphism and compile-time Polymorphism?
In Java, all non-static non-final methods are virtual methods by default, so if a subclass has a method with the same signature (same input types, same output type) that the super class, this method is being overridden even if that wasn't your intention. The compiler will even raise a warning stating that the method in the subclass must use the #Override annotation to inform other programmers that this method is being overridden.
In Java, according to this tutorial, it's called compile time polymorphism to method overloading (such an odd name).
4.If no, Please give me an example where Polymorphism is seen.
You already have such example for method overriding (dynamic).
Here's another example for method overloading (static):
public class Foo {
public void print(int x) {
System.out.println("Printing number: " + x);
}
public void print(String x) {
System.out.println("Printing string: " + x);
}
public static void main(String[] args) {
Foo foo = new Foo();
foo.print(5);
foo.print("5");
}
}
Output:
Printing number: 5
Printing string: 5
Is Polymorphism a concept only related to Overriding methods?
Polymorphism applies to METHODS only. To non-static and non-final METHODS.
Is the first code block is relevant to Polymorphism?
Not really, in first block you don't override, you hide the ab() method. It's the rules in section 8.4.8.3 of the JLS, "Requirements in Overriding and Hiding":
If yes, What is run-time Polymorphism and compile-time Polymorphism?
If no, Please give me an example where Polymorphism is seen.
Better than writting a fast code, check this tutorial
Your questions:
Is Polymorphism a concept only related to Overriding methods?
Yes - Java only implements polymorphism on methods of classes. The way you tried it on a data type doesn't work.
Is the first code block is relevant to Polymorphism?
Yes, it's a pretty typical example of run-time polymorphism,
If yes, What is run-time Polymorphism and compile-time Polymorphism?
Your working example is a typical run time situation. We call this run-time because only when the code is actually running can we figure out that a1 is actually a instance of B not an instance of A
Compile-time polymorphism is the situation when one method is chosen over another method with the same name when the code is compiled because of the types associated with it.
I am a new hand of Java programming, so if there is anything misused, remind and excuse me.
I can make polymorphism when dealing with class types, say:
class A{}
class B{}
void method(Object obj){
if (obj instanceof A) {}
else if (obj instance of B){}
else {}
}
I can pass different classes to call different part of method(), but when dealing with basic types like int, it is not inherited from Object.
I know actually this is not strict polymorphism, because there is not override. Maybe, generic programming is a more proper name, but I don't know whether this is right.
If you are trying to do what you are talking about (which isn't quite polymorphism) with basic data types, you could try to use Integers, instead of ints. ints are raw data, which are stored by their value. Integer is a class, and has all the functionality of one (plus auto-boxing/unboxing, but don't worry about that).
Because Integer is a class, you can extend it and do what your are talking about with the instanceof stuff.
There are also (Long)s, (Double)s, (Boolean)s, et cetera
You can define few methods with the same name and different argument types like that:
void method(int a) {}
void method(long a) {}
void method(double a) {}
As #ByteCommander mentioned it's called overloading
I think it's what you meant. In this case when you call:
int a = 1; method(a);
you will execute first method defined. And so on...
I don't understand the overloading in Java. Is there a relation with polymorphism ? It seems very abstract for me.
I come more from Javascript language ? Would this apply so in Javascript ?
Overloading means that the same method name can be defined with more than one signature — the list of formal parameters (and their types).
Overloading means different things in different languages. Java is strongly typed (some might say "fiercely typed" in fact). It just means that there can be different versions of a function and the compiler can tell which one is intended by looking at the types of parameters in a call to the function (method).
JavaScript is not like that; the formal parameters to a function are just references by name in the function body, but otherwise there's nothing special about them and any function can be called with any arguments and any number of them.
Some languages use "overloading" as a runtime concept. In Erlang, it's not the types of arguments that matter when picking from several alternative versions of a function; it's the values.
edit — #MarkoTopolnik points out that the issue isn't so much about the "strength" (or "ferocity" :-) of the type system, but about how static it is. Java insists on types being explicitly declared pretty much everywhere, while JavaScript (excepting some of the new typed array constructs) doesn't.
Overloading is feature that allows having 2 methods with the same name and different signature in one class, e.g.
public void foo();
public void foo(int i);
Now you can call method foo() without arguments or with one int argument and different methods will be executed.
You are probably confused with overloading and overriding. Overriding indeed relate to polimorphysm. This is ability to overrride (change) functionality of base class into subclass. For example if Child extends Base and both have method foo() the foo() of child overrides implementation of Base. Similar feature indeed exists in JavaScript.
if you have following method in your class
public void calculate() {}
Following are some overloaded versions of it.(Note same name)
public void calculate(int i) {}
public void calculate(int i, int j) {}
But following is not an overloaded one of above method. This method differs from the original method only just because the return type. Methods with same signature but with different return types are not allowed in java.
public int calculate(int i) {}
The method which have same name with multiple definition is known as overloading
may be its differ from argument type and number of arguments.
Example
import java.io.*;
class demoOverloading
{
int add(int x,int y) //method definition
{
return (x+y);
}
double add(double x,double y) //method definition
{
return (x+y);
}
}
public class JavaApplication4
{
public static void main(String[] args)
{
demoOverloading demo=new demoOverloading(); //creating object for above class
System.out.println("Sum of Integer "+demo.add(10,20)); //calling integer add method
System.out.println("Sum of double "+demo.add(33.44,67.5)); //calling double add method
}
}
The above example having two methods having same name add but one contains int and another contains double arguments, like this we can made with different argument,,
Also possible made difference in number of arguments..
Thank you
I know quite a bit how to use C++-Templates -- not an expert, mind you. With Java Generics (and Scala, for that matter), I have my diffuculties. Maybe, because I try to translate my C++ knowledge to the Java world. I read elsewhere, "they are nothing alike: Java Generics are only syntactic sugar saving casts, C++ Templates are only a glorified Preprocessor" :-)
I am quite sure, both is a bit simplified a view. So, to understand the big and the subtle differences, I try to start with Specialization:
In C++ I can design a Template (class of function) that acts on any type T that supports my required operations:
template<typename T>
T plus(T a, T b) { return a.add(b); }
This now potentially adds the plus() operation to any type that can add().[note1][1]
Thus, if T supports the add(T) my template woll work. If it doesn't,
The compiler will not complain as long as I do not use plus(). In Python
we call this "duck typing": *If it acts like a duck, quacks like a duck,
it is a duck.* (Of course, with using type_traits this is modified a bit,
but as long as we have no concepts, this is how C++ Templates work, right?)
I guess, thats how Generics in Java work as well, isn't it? The generic type I device is used as a "template" how to operate on any anything I try to put in there, right? As far as I understand I can (or must?) put some constraints on the type arguments: If I want to use add in my template, I have to declare the type argument to implement Addable. Correct? So, no "duck typing" (for better or worse).
Now, in C++ I can choose to specialize on a type that has no add():
template<>
T plus<MyX>(MyX a, MyX b) { return a + b; }
And even if all other types still can use the "default" implementation, now I added a special one for MyX -- with no runtime overhead.
Is there any Java Generics mechanism that has the same purpose? Of course, in programming everything is doable, but I mean conceptually, without any tricks and magic?
No, generics in Java don't work this way.
With generics you can't do anything which would not be possible without Generics - you just avoid to have to write lots of casts, and the compiler ensures that everything is typesafe (as long as you don't get some warnings or suppress those).
So, for each type variable you can only call the methods defined in its bounds (no duck typing).
Also, there is no code generation (apart from some adapter methods to delegate to methods with other parameter types for the purpose of implementing generic types). Assume you had something like this
/**
* interface for objects who allow adding some other objects
*/
interface Addable<T> {
/** returns the sum of this object and another object. */
T plus(T summand);
}
Then we could create our sum method with two arguments:
public static <T extends Addable<T>> T sum(T first, T second) {
return first.plus(second);
}
The static method is compiled to the same bytecode like this (with additional type information in annotations):
public static Addable sum(Addable first, Addable second) {
return first.plus(second);
}
This is called type erasure.
Now this method can be called for every pair of two elements of an addable type, like this one:
public class Integer implements Addable<Integer> {
public Integer plus(Integer that) {
return new Integer(this.value + that.value);
}
// private implementation details omitted
}
What here happens is that the compiler creates an additional synthetic method like this:
public Object plus(Object that) {
return this.plus((Integer)that);
}
This method will only be called by generic code with the right types, this guarantees the compiler, assuming you are not doing some unsafe casts somewhere - then the (Integer) cast here will catch the mistake (and throw a ClassCastException).
The sum method now always calls the plus method of the first object, there is no way around this. There is not code generated for every type argument possible (this is the key difference between Java generics and C++ templates), so we can't simply replace one of the generated method with a specialized one.
Of course, you can create a second sum method like irreputable proposed (with overloading), but this will only be selected if you use the MyX type directly in source code, not when you are calling the sum method from some other generic code which happens to be parametrized with MyX, like this:
public static <T extends Addable<T>> product (int times, T factor) {
T result = factor;
while(n > 1) {
result = sum(result, factor);
}
return result;
}
Now product(5, new MyX(...)) will call our sum(T,T) method (which in turn calls the plus method), not any overloaded sum(MyX, MyX) method.
(JDK 7 adds a new dynamic method dispatch mode which allows specialization by every argument on run time, but this is not used by the Java language, only intended to be used by other JVM-based languages.)
no - but your particular problem is more of an overloading issue.
There's no problem to define 2 plus methods like these
<T extends Addable>
T plus(T a, T b) { .. }
MyX plus(MyX a, MyX b) { .. }
This works even if MyX is an Addable; javac knows that the 2nd plus is more specific than the 1st plus, so when you call plus with two MyX args, the 2nd plus is chosen. In a sense Java does allow "specialized" version of methods:
f(T1, T2, .. Tn)
f(S1, S2, .. Sn)
works great if each Si is a subtype of Ti
For generic classes, we can do
class C<T extends Number> { ... }
class C_Integer extends C<Integer>{ ... }
caller must use C_Integer instead of C<Integer> to pick the "specialized" version.
On duck typing: Java is more strict in static typing - unless it is a Duck, it is not a duck.
HI,
java Generics it's different from C++ template.
Example:
Java code:
public <T> T sum(T a, T b) {
T newValue = a.sum(b);
return newValue;
}
In java this code don't work because generics base is class java.lang.Object, so you can use only method of this class.
you can construct this methis like this:
public <T extends Number> T sum(T a, T b) {
T newValue = a.sum(b);
return newValue;
}
in this case the base of generics is class java.lang.Number so you can use Integer, Double, Long ecc..
method "sum" depend of implementation of java.lang.Number.
Bye