Types of Polymorphism
Cardelli defines several types of polymorphism in this article:- Universal
- parametric
- inclusion
- Ad-hoc
- overloading
- coercion
1.) Cases of covariance and contravariance with generics.
2.) Arrays are Serializable and Cloneable although this is not evident anywhere in the type hierarchy.
3.) Concatenation of strings and numbers or of a string plus some other object. Consider also the cases of boxing and unboxing of primitives.
4.) cases of polymorphism (coercion and overloading) are not at all related to inheritance.
Examples
Inclusion
List<Integer> myInts = new ArrayList<Integer>();
|
And in other cases, the relationships are not even evident in the API
Cloneable clone = new int[10];
Serializable obj = new Object[10]
Parametric
The same algorithm can be used to filter all kinds of lists with all
kinds of predicates without having to repeat a single line of code for
every possible type of list.
double sum = 1 + 2.0;
Integer and floating-point arithmetic are totally different. Applying
the plus operator to two operands of different types here is impossible
without some form of coercion.Types of Polymorphism
Cardelli defines several types of polymorphism in this article:- Universal
- parametric
- inclusion
- Ad-hoc
- overloading
- coercion
Wikipedia provides a good definition:
In object-oriented programming, subtype polymorphism or inclusion polymorphism is a concept in type theory wherein a name may denote instances of many different classes as long as they are related by some common super class. Inclusion polymorphism is generally supported through subtyping, i.e., objects of different types are entirely substitutable for objects of another type (their base type(s)) and thus can be handled via a common interface. Alternatively, inclusion polymorphism may be achieved through type coercion, also known as type casting.Another Wikipedia article called Polymorphism in object-oriented programming seems to answer your questions as well.
In Java
This subtyping feature in Java is achieved, among other means, through the inheritance of classes and interfaces. Although the subtyping features of Java may not be evident in terms of inheritance all the time. Take for example the cases of covariance and contravariance with generics. Also, arrays are Serializable and Cloneable although this is not evident anywhere in the type hierarchy. It can also be said that through primitive widening conversion the numeric operators in Java are polymorphic, in certain cases even accepting totally unrelated operands (i.e. concatenation of strings and numbers or of a string plus some other object). Consider also the cases of boxing and unboxing of primitives. These latter cases of polymorphism (coercion and overloading) are not at all related to inheritance.Examples
InclusionList<Integer> myInts = new ArrayList<Integer>();
This is the case to which your question seems to refer i.e. when
there is an inheritance or implementation relationship between the
types, as in this case where ArrayList implements List.As I mentioned, though, when you introduce Java generics, some time the rules of subtyping get fuzzy:
List<? super Number> myObjs = new ArrayList<Object>();
List<? extends Number> myNumbers = new LinkedList<Integer>();
And in other cases, the relationships are not even evident in the APICloneable clone = new int[10];
Serializable obj = new Object[10]
Even so, all these, according to Cardelli, are forms of universal polymorphism.Parametric
public <T> List<T> filter(Predicate<T> predicate, List<T> source) {
List<T> result = new ArrayList<>();
for(T item : source) {
if(predicate.evaluate(item)){
result.add(item);
}
return result;
}
}
The same algorithm can be used to filter all kinds of lists with all
kinds of predicates without having to repeat a single line of code for
every possible type of list. The type of the actual list and the type of
predicate are parametric. See this example with lambda expressions
available in JDK 8 Preview (for the brevity of predicate implementation).filter(x -> x % 2 == 0, asList(1,2,3,4,5,6)); //filters even integers
filter(x -> x % 2 != 0, asList(1L,2L,3L,4L,5L,6L)); //filters odd longs
filter(x -> x >= 0.0, asList(-1.0, 1.0)); //filters positive doubles
According to Cardelli, this is a form of universal polymorphism.Coercion
double sum = 1 + 2.0;
Integer and floating-point arithmetic are totally different. Applying
the plus operator to two operands of different types here is impossible
without some form of coercion.In this example, the types integer and double, are automatically coerced (converted) to type double without an explicit cast. The entire expression is promoted to double. This is so because in Java we have primitive widening conversions.
According to Cardelli, this form of automatic coercion is a form of ad-hoc polymorphism provided for the plus operator.
There are languages in which you could not even sum an integer and a floating-point number without an explicit cast (i.e. AFAIK, SML, in which, by the way, parametric polymorphism is key to overcome this kind of problems).
Overloading
double sum = 2.0 + 3.0;
String text = "The sum is" + sum;
The plus operator here means two different things depending on the
arguments used. Evidently, the operator has been overloaded. This
implies it has different implementations depending on the types of
operands. According to Cardelli, this is a form of ad-hoc polymorphism
provided for the plus operator.
No comments:
Post a Comment