Solved

What is covariance in Java?

Posted on 2011-09-13
19
334 Views
Last Modified: 2012-05-12
In my Java book it says:

"If we pass a Collection<Shape> below, the code works. However, what happens if we pass a Collection<Square>? The answer depends on whether a Collection<Square> IS-A Collection<Shape>. Recall that the technical term for this is whether we have covariance."

What do they mean by "IS-A" and what do they mean by covariance? Is covariance just whether or not Square inherits from Shape?
public static double totalArea( Collection<Shape> arr )
{

}

Open in new window

0
Comment
Question by:shampouya
  • 11
  • 6
  • 2
19 Comments
 
LVL 47

Expert Comment

by:for_yan
ID: 36532753
IS-A is a way to talk about inheritance

if class B inherits from class A then each instance of B in fact IS an instance of  A

this is usually is opposed to another realtion beteeen the classes
when a vraibale of class B is a field in the class A - in this case you would
say that A   HAS an instance of B

This is not juist matter of language - sometimes when you design your objects
it is importnat to make decision wheretehre you want to create class B as a child inheriting from A,
or you want to make it so that class A is in fact a wrapper around class B (conatains B as a field)
And depending on the use of those classes in your applications somethimes
one arrangement is prefereable to the alternative

 

0
 
LVL 47

Expert Comment

by:for_yan
ID: 36532784
Covariance is another story

Perhaps this response in
http://stackoverflow.com/questions/2660827/java-generics-covariance

would explain you what is covariance and the lack threof for java generics
------------------------
List<Integer> li = new ArrayList<Integer>();
List<Number> ln = li; // illegal
ln.add(new Float(3.1415));

In Java, Integer inherits from Number(java.lang.Number), so intuitively, anything that is an Integer(java.lang.Integer) is also a number, but what that article points out is that with generics it does not work that way, because considering that example, you could end up putting a float (which is a Number) into a List<Integer>, which is illegal because a float is not an integer.

Conclusion: Generics are not covariant.

Note: I recommend you read Effective Java (2nd Edition) Chapter 5: Generics.

------------------------
0
 
LVL 47

Assisted Solution

by:for_yan
for_yan earned 250 total points
ID: 36532820

I would even say it maybe simpler as in the second answer to that same question

Even though Float inherits from Object
List<Float> does not inherit from List<Object>

Therefroere

ArrayList<Float> fl = ArrayList<Float>();

Object o;

fl.add(o); <--- this will be illegal


0
 
LVL 47

Expert Comment

by:for_yan
ID: 36532834
The same applies to your exmaple - eeven though Square inherits from Shape
Collection<Square> does not inherit from Collection<Shape>
This is what is implied whien they sya that there is no covariance in Java generics
 
0
 
LVL 26

Accepted Solution

by:
dpearson earned 250 total points
ID: 36532837
Covariance in software languages deals with the question of when can you substitute one class for another related class.

We're all used to standard inheritance:

public static int area(Shape shape) {
}

can be called with area(Square) if Square inherits from Shape.

That's a simple IS-A relationship between Square and Shape ("a square IS A shape").

Covariance comes into play when we look at List<Square> and List<Shape> and whether it should be OK to pass List<Square> into a method expecting List<Shape>.

It may be obvious to you that you should be able to pass a List<Square> to a method that takes a List<Shape> but remember it's Square that inherits from Shape.  The type List<Square> is not directly related to the type List<Shape> - except that they're two lists.

If the language allows you to pass List<Square> to a List<Shape> then we say it supports covariance - because the language is saying these two types are compatible even though they don't directly inherit from each other.  Another way to look at that is to say that if they support this covariance then the "is a" relationship holds ("a list of squares IS A list of shapes") - but there's no direct inheritance here between those two lists.  There's just inheritance between the two classes Square and Shape.

Hope that helps.
0
 

Author Comment

by:shampouya
ID: 36533953
Ok thanks, and my teacher said that Wildcards are used to get around the lack of covariance between  List<Square> and List<Shape>

Could you briefly explain how the wildcard works? Is it something like this?

List<Shape extends Square>
0
 
LVL 47

Expert Comment

by:for_yan
ID: 36533963
You can write List<? extends Shape> shapes

You can read more details here:

http://download.oracle.com/javase/tutorial/extra/generics/wildcards.html

0
 
LVL 47

Expert Comment

by:for_yan
ID: 36533990
Read both about Wildcards and about Bounded Wildcards in the above link

Although I quoted Bounded Wildcard above, but the talk about unbounded wildcard even better explains how
wildcards allow to get around of the lack of covariance
0
 
LVL 26

Expert Comment

by:dpearson
ID: 36534029
As for_yan said you can use List<? extends Shape>.

That can be a bit hard to read and understand.

You want to think of the "?" as being your class.  So this means in English "a list of objects of some unknown type - where that type inherits from Shape".  The "unknown type" is the "?" - or the wildcard.

Doug
0
Why You Should Analyze Threat Actor TTPs

After years of analyzing threat actor behavior, it’s become clear that at any given time there are specific tactics, techniques, and procedures (TTPs) that are particularly prevalent. By analyzing and understanding these TTPs, you can dramatically enhance your security program.

 

Author Comment

by:shampouya
ID: 36534882
So in my case, List<Square extends Shape> would be the correct use of a wildcard?
0
 
LVL 47

Expert Comment

by:for_yan
ID: 36534894
No, you can say

List<? extends Shape>

List<Square extends Shape> this does not have a wild card

0
 
LVL 47

Expert Comment

by:for_yan
ID: 36534900
The main thing is to have wild card, otherwise you jaust can say
List<Square>
0
 

Author Comment

by:shampouya
ID: 36535918
I can say List<Square>? I thought that I cannot say List<Square>. I thought I needed to pass List<? extends Shape> for it to work.
0
 
LVL 47

Expert Comment

by:for_yan
ID: 36536006
You can say List<Square> but that means that you can have only List where each element is Square
 
When you say List<? Extends Shape> then the same code can be reused for List<Square> and for List<Circle>
0
 

Author Comment

by:shampouya
ID: 36536096
Ok cool. So are my two definitions correct so far?

Covariance - the question of when can you substitute one class for another class when they are not directly related to each other. Covariance isn’t an issue If one class inherits from another class, because you can substitute the subclass object for the parent class object without any problems. For example, let’s say the Square class inherits from the Shape class, in what is referred to as an “IS-A” relationship between Square and Shape ("a square IS A shape"). Now let’s say there is a method that takes a Shape object as an argument. Thanks to standard inheritance we can accept a Square object as an argument in this method in place of Shape. And because arrays are covariant in Java, we can even accept the array Squares[ ] if the method expects a Shapes[ ] argument, even though the arrays themselves are unrelated. But generic collections are not covariant like normal objects are. If you wanted to pass ArrayList<Float> as an argument instead of ArrayList<Object>, you would get a compiler error. The objects inside of these ArrayLists are related, but the collections as a whole are not related.


Wildcards - a tool introduced in Java 5 to indicate when subclasses of the expected parameter type are being used in collections. For example, if the Square class inherits from the Shape class, then you can pass ArrayList<Square> instead of ArrayList<Shape> IF the method that is being called has ArrayList<? extends Shape> in the parameter of its method signature. The question mark is the wildcard, and it indicates the unknown type that inherits from the Shape class. This helps work around the problem of generic collections not being covariant in Java.
0
 
LVL 47

Expert Comment

by:for_yan
ID: 36536192
Your second point is not entirely accurate because wildcards in generics can exist not necessarily in the form <? extends SomeClass>
The wildcard ? stnds for an unknown class in the generics definition. <? extends SomeClass> is just a case of wildcards which reads unknoen class which extends SomeClas.
However as you can see in the first half of this page:


http://download.oracle.com/javase/tutorial/extra/generics/wildcards.html

you can use wildcard in definition like that Collection<?>  also

0
 

Author Comment

by:shampouya
ID: 36536205
Ok thx I'll change that. My covariance definition is good though?
0
 
LVL 47

Expert Comment

by:for_yan
ID: 36536232


You covariance definition is good enough and has what is essential for us
though if you want to see more general definition, you can look here:

http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)
0
 

Author Closing Comment

by:shampouya
ID: 36536291
thanks
0

Featured Post

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Suggested Solutions

Title # Comments Views Activity
json example 39 115
mapAB Challlenge 35 89
@SBGen Method 3 25
JAVA part two 5 41
For customizing the look of your lightweight component and making it look opaque like it was made of plastic.  This tip assumes your component to be of rectangular shape and completely opaque.   (CODE)
Java functions are among the best things for programmers to work with as Java sites can be very easy to read and prepare. Java especially simplifies many processes in the coding industry as it helps integrate many forms of technology and different d…
Viewers learn about the “while” loop and how to utilize it correctly in Java. Additionally, viewers begin exploring how to include conditional statements within a while loop and avoid an endless loop. Define While Loop: Basic Example: Explanatio…
Viewers learn about the scanner class in this video and are introduced to receiving user input for their programs. Additionally, objects, conditional statements, and loops are used to help reinforce the concepts. Introduce Scanner class: Importing…

746 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

12 Experts available now in Live!

Get 1:1 Help Now