I just met an strange case when reading the Java doc. Here is the link to Oracle's java doc on Arrays.asList method, http://docs.oracle.com/javase/7/docs/api/java/util/Arrays.html#asList(T...)
There is an example in the doc
List<String> stooges = Arrays.asList("Larry", "Moe", "Curly");
My question is, as List is an interface, why can we declare stooges as a 'List', rather than a concrete subclass implementing List(e.g. ArrayList or LinkedList)?
So does it mean that we can have a reference variable of interface type? It looks quit weird to me as I always think that interface stands only for polymorphism, and we should never really use a interface type variable.
Could anyone please give me some clue on this?
Think of the List interface as a guarantee. Any class that implements List will be guaranteed to have the methods of the interface. When Arrays.asList() returns a List you're not actually getting an interface, you're getting a concrete class that is guaranteed to implement the methods listed in the List interface.
As to your "we should never really use a interface type variable" you're actually suppose to do that. It's called "programming to the interface". It's much more flexible if you can return a List as opposed to something like a LinkedList. The caller of your method isn't coupled to your specific implementation internal implementation which might use, and return, a LinkedList. If at some point you wanted to return a ArrayList instead of the LinkedList the caller would not have to change any code because they only care about the interface.
What does it mean to "program to an interface"?
Just a word of note, Serializable is a marker interface and a little odd because of that. It doesn't guarantee that methods are there, but instead guarantees that the creator of the class that implements serializable has thought about the many issues associated with serializing a class (overriding readObject/writeObject, compatiblity with other serialized forms, and other issues http://www.javapractices.com/topic/TopicAction.do?Id=45). So Serializable is still offering a guarantee, like List is, but it isn't about method signatures, it's about an extralinguistic feature of the language.
http://en.wikipedia.org/wiki/Marker_interface_pattern
Using an Interface as a reference type is a perfectly valid practice in Java. For example, the Serializable interface will do this inside it's class, so that any object that is passed to it can be serialized.
This is also how Java provides something that resembles Multiple Inheritance. For example:
public interface A { }
public class B implements A {}
public class program {
B bClass = new B();
A aObject = (A)bClass;
}
That way the same object can be referenced with different reference types, and all without messing up an inheritance chain!
The interface defines a contract or a specification for an implementation. Which is the methods and their signature. So a class that implements an interface has to respect that contract. This way you can change implementation without affecting the code that uses interfaces for declaring variables.
In the example you mentioned:
You don't know what implementation of the List interface Arrays.asList is using unless you look into the code. So how would you know which one to use? (see javadoc for list interface to see what implementations it has)
The implementation is subject for change, what if Arrays.asList decides to use another implementation? Your code will be broken.
The signature of the method Arrays.asList is that it returns List<T> so if you want to have a concrete implementation as variable you'll have to cast that return value which is bad practice or to create new - let's say ArrayList - and copy all the elements into it, which is just an unnecessary overhead.
Effective Java by Bloch is a great book on Java best practices. In particular, item #52 talks about this: "If the appropriate interface types exist ... declared using the interface types."
The general notion is that, for greatest flexibility and understandability, you should use the type that best reflects the context, which is usually the interface. In the example, you provided, does the exact implementation matter or just that it is a List. Of course, if the code requires an ArrayList-specific method or if the code is relies on an ArrayList-specific behavior, then use the concrete class.
There are occasional exceptions, such as when using GWT-RPC, but this is for implementation reasons.
This is really good example of polymorphism power, if you like you can look at the source code of Arrays.asList() here Arrays.asList(T...a) ,you will find that it takes varibale length input and defines its own private static concrete class ArrayList that implements List interface rather than using the well known java.util.ArrayList or other java Collection type,
this may be to make it more efficient or something, you want to implement your own class and you return it to the user without overwhelming him by implementation details since there is an interface he can deal with your private class through.
Related
Why do many Collection classes in Java extend the Abstract class and also implement the interface (which is also implemented by the given abstract class)?
For example, class HashSet extends AbstractSet and also implements Set, but AbstractSet already implements Set.
It's a way to remember that this class really implements that interface.
It won't have any bad effect and it can help to understand the code without going through the complete hierarchy of the given class.
From the perspective of the type system the classes wouldn't be any different if they didn't implement the interface again, since the abstract base classes already implement them.
That much is true.
The reason they do implement it anyways is (probably) mostly documentation: a HashSet is-a Set. And that is made explicit by adding implements Set to the end, although it's not strictly necessary.
Note that the difference is actually observable using reflection, but I'd be hard-pressed to produce some code that would break if HashSet didn't implement Set directly.
This may not matter much in practice, but I wanted to clarify that explicitly implementing an interface is not exactly the same as implementing it by inheritance. The difference is present in compiled class files and visible via reflection. E.g.,
for (Class<?> c : ArrayList.class.getInterfaces())
System.out.println(c);
The output shows only the interfaces explicitly implemented by ArrayList, in the order they were written in the source, which [on my Java version] is:
interface java.util.List
interface java.util.RandomAccess
interface java.lang.Cloneable
interface java.io.Serializable
The output does not include interfaces implemented by superclasses, or interfaces that are superinterfaces of those which are included. In particular, Iterable and Collection are missing from the above, even though ArrayList implements them implicitly. To find them you have to recursively iterate the class hierarchy.
It would be unfortunate if some code out there uses reflection and depends on interfaces being explicitly implemented, but it is possible, so the maintainers of the collections library may be reluctant to change it now, even if they wanted to. (There is an observation termed Hyrum's Law: "With a sufficient number of users of an API, it does not matter what you promise in the contract; all observable behaviors of your system will be depended on by somebody".)
Fortunately this difference does not affect the type system. The expressions new ArrayList<>() instanceof Iterable and Iterable.class.isAssignableFrom(ArrayList.class) still evaluate to true.
Unlike Colin Hebert, I don't buy that people who were writing that cared about readability. (Everyone who thinks standard Java libraries were written by impeccable gods, should take look it their sources. First time I did this I was horrified by code formatting and numerous copy-pasted blocks.)
My bet is it was late, they were tired and didn't care either way.
From the "Effective Java" by Joshua Bloch:
You can combine the advantages of interfaces and abstract classes by adding an abstract skeletal implementation class to go with an interface.
The interface defines the type, perhaps providing some default methods, while the skeletal class implements the remaining non-primitive interface methods atop the primitive interface methods. Extending a skeletal implementation takes most of the work out of implementing an interface. This is the Template Method pattern.
By convention, skeletal implementation classes are called AbstractInterface where Interface is the name of the interface they implement. For example:
AbstractCollection
AbstractSet
AbstractList
AbstractMap
I also believe it is for clarity. The Java Collections framework has quite a hierarchy of interfaces that defines the different types of collection. It starts with the Collection interface then extended by three main subinterfaces Set, List and Queue. There is also SortedSet extending Set and BlockingQueue extending Queue.
Now, concrete classes implementing them is more understandable if they explicitly state which interface in the heirarchy it is implementing even though it may look redundant at times. As you mentioned, a class like HashSet implements Set but a class like TreeSet though it also extends AbstractSet implements SortedSet instead which is more specific than just Set. HashSet may look redundant but TreeSet is not because it requires to implement SortedSet. Still, both classes are concrete implementations and would be more understandable if both follow certain convention in their declaration.
There are even classes that implement more than one collection type like LinkedList which implements both List and Queue. However, there is one class at least that is a bit 'unconventional', the PriorityQueue. It extends AbstractQueue but doesn't explicitly implement Queue. Don't ask me why. :)
(reference is from Java 5 API)
Too late for answer?
I am taking a guess to validate my answer. Assume following code
HashMap extends AbstractMap (does not implement Map)
AbstractMap implements Map
Now Imagine some random guy came, Changed implements Map to some java.util.Map1 with exactly same set of methods as Map
In this situation there won't be any compilation error and jdk gets compiled (off course test will fail and catch this).
Now any client using HashMap as Map m= new HashMap() will start failing. This is much downstream.
Since both AbstractMap, Map etc comes from same product, hence this argument appears childish (which in all probability is. or may be not.), but think of a project where base class comes from a different jar/third party library etc. Then third party/different team can change their base implementation.
By implementing the "interface" in the Child class, as well, developer's try to make the class self sufficient, API breakage proof.
In my view,when a class implements an interface it has to implement all methods present in it(as by default they are public and abstract methods in an interface).
If we don't want to implement all methods of interface,it must be an abstract class.
So here if some methods are already implemented in some abstract class implementing particular interface and we have to extend functionality for other methods that have been unimplemented,we will need to implement original interface in our class again to get those remaining set of methods.It help in maintaining the contractual rules laid down by an interface.
It will result in rework if were to implement only interface and again overriding all methods with method definitions in our class.
I suppose there might be a different way to handle members of the set, the interface, even when supplying the default operation implementation does not serve as a one-size-fits-all. A circular Queue vs. LIFO Queue might both implement the same interface, but their specific operations will be implemented differently, right?
If you only had an abstract class you couldn't make a class of your own which inherits from another class too.
I am following Oracle's online tutorial for Java and am puzzled by a particular line of code.
The full code for the example I am looking at is here: http://docs.oracle.com/javase/tutorial/java/javaOO/innerclasses.html
The particular line that bothers me is in the DataStructure class' printEven() method:
DataStructureIterator iterator = this.new EvenIterator();
I don't understand why the interface DataStructureIterator is used as the type for iterator when the actual type, EvenIterator, which I tried, works just as fine and makes more sense to me:
EvenIterator iterator = this.new EvenIterator();
It only make sense if your code must have an EvenIterator.
Otherwise the more-generalized interface should be preferred, allowing you to change the underlying implementation without any further code changes.
As a (somewhat contrived) concrete example, it might make sense to use only an ArrayList to enforce constant-time indexed access; in that case you might want to avoid the more-generalized List to make sure you don't blow up the timing of your app.
Interfaces are used to abstract the essence of the implementation in a neat type, and can and even should be used as references to the implementing types. This makes client classes agnostic of the real implementing classes, making the design more robust.
The example's choice of DataStructureIterator for the type of the variable is a stylistic one. It is valid because EvenIterator is a subtype of DataStructureIterator, so that every EvenIterator is also a DataStructureIterator.
As a rule of thumb, it is usually best for variables and method parameters to be typed as generally as possible, and for method return values to be typed as specifically as possible. That affords more flexibility to your code. How general or how specific "is possible" is a judgement call you must make, based on the nature of the code and how you intend for it to be used.
The reason you can use that interface is because EvenIterator is a DataStructureIterator. You should always use interfaces when creating a reference, as you don't usually need to know the specific implementation. Interfaces define a contract that implementing classes must conform to. Using interfaces helps to minimize coupling.
Using a simple example, an Animal (interface) can run (void run() method). Then, you want to have Dog and Cat classes and both of them can run, so you implement that interface. Now, you want to keep a list of animals that can run, so you should use Animal references instead of Dog or Cat, as all you need to know is that an Animal can run, not which kind of animal are you using.
Their example code is a bit sloppy. It would have been better as:
Iterator<Integer> iterator = this.new EvenIterator();
This makes it clear that the code using the Iterator only cares that it needs an Iterator (in this case of Integer). Experienced Java programmers often see code like that in the example and expect to find some specific reason for the code to need, in this case, DataStructureIterator. Usually the most general applicable type is clearer and makes less assumptions. For example, I habitually write:
List<V> list = new ArrayList<V>();
(Which I read as 'I need a list, it happens to be an ArrayList but that is irrelevant to the rest of the logic'.)
Joshua Bloch in his Effective Java book dedicates a whole item to this topic - "Refer to objects by their interfaces", and a part of it I would like to quote here:
If appropriate interface types exist, then parameters, return values, variables, and fields should all be declared using interface types.
...
If you get into the habit of using interfaces as types, your program will be much more flexible. If you decide that you want to switch implementations, all you have to do is change the class name in the constructor (or use a different static factory).
I know that in Java most people declare a list using:
List l = new ArrayList();
But what would be the difference between that and
AbstractList l = new ArrayList();
What are the advantages of using an interface over an abstract class in this particular instance?
Original answer:
An abstract class allows you to define some shared functionality, while leaving other functionality to be defined by implementations. Thus, abstract classes are useful if you are going to create a family of similar classes that share some functionality but have customizations.
An interface doesn't allow you to define any functionality. It simply defines a set of method signatures that you know can be called on any object of a class that implements that interface.
I'd say the accepted practice is not to use an abstract class to fill the role of an interface. That is, an abstract class should be used for code sharing among related classes that you define, whereas an interface should be used for abstraction.
One reason not to use abstract classes to fill the role of interfaces is that a class cannot inherit from more than one class, but it can implement many interfaces. Thus, using abstract classes limits your design a lot more than using interfaces does.
Edit:
In this particular instance, the difference would be that if you later reassigned l to contain an object that implements List but does not derive from AbstractList, your code will throw an exception. Not all classes that implement List also extend AbstractList.
Using AbstractList limits you to only working with lists that are derived from the core AbstractList functionality. On the other hand, anyone could write a class that implements List using totally new code, and if you're using a variable of type List then you'll still be compatible with their new class that you've never seen before.
The fact that Java's lists are derived from AbstractList should be treated as an implementation detail that's internal to the Java library, not as an interface that you should code against.
The hierarchy is like...
ArrayList extends AbstractList implements List
and
AbstractList implements List
So,
whenever you are creating a object of ArrayList like given below, You will be creating object of ArrayList with reference of List
List list = new ArrayList();
Another thing to note is, why it is required to implement List in both class,
So,
it is for the purpose of showing that ArrayList implements List.
AbstractList in the whole picture is just for convenience and to
reduce code duplication between List implementations.
Reference: This SO Answer
In this case it wouldn't be really different. However it's a common code style to use the interface as the variable type, as the abstract implementation of AbstractWhatever class is mean to make it easier to create an implementation without having to implement all of the methods in the interface.
So it's a style issue, not really a technical one.
I have a confusion in different ways the objects are created which I have seen in java docs and other programming books. For e.g.
Assuming there is a base class and a derived class
1- I have a variable of type Base which refers to the object of type Derived
List<String> list = new ArrayList<String>();
2- I have a variable of type Derived which refers to the object of type Derived
ArrayList<String> arrList = new ArrayList<String>();
My question is what should be my thinking while choosing between 1 and 2? Is it to take advantage of Polymorphism in general Base-Derived scenarios?
Is there a better practice while choosing between 1 and 2 that I am not aware of or is it just a personal decision?
EDIT:
Sorry, List is an interface.
Another question: Will my decision change if I use a Type parameter?
ArrayList<T> list = new ArrayList<T>();
Update Answer: This is actually called "Programming to the interface". Thanks Code-Guru. Exactly what I was looking for is explained in very simple terms in one of the answers to this question - What does it mean to "program to an interface"?
List is not a base class it is an interface and therefore should be used wherever possible.
Using the interface that a class implements allows you to work with all classes that implement the interface, not just the specific class.
String is a concrete class so it is much clearer to use it directly.
Sometimes, however, even though String implements the CharSequence interface it is unnecessary to use CharSequence because it would just be confusing. However, take a look at StringBuilder, it uses CharSequence almost exclusively.
In summary - there is no better there is just appropriate.
Choosing the base type allows you to at some point in the future change between using an ArrayList to say a LinkedList, without changing the rest of the code. This gives you more flexibility to refactor later on. Likewise, your public methods should return a List instead of the specific type of List implementation for the same reason -- so that you may change your internal implementation to optimize performance without breaking the contract to your callers.
In the case where List is a class ( just assume for the purpose of answering your question - "Shall we use object of Parent class representing child class or use object of type derived class ( actula class) ? "
1) You were correct, its solely for the purpose of polymorphism.
2) Mostly its used for Passing the object around different class methods. Other classes' methods may be accepting parent class a input. you have to use the casting in those places.
Here's an example using multiple interface inheritance in Java and there's an issue.
Note that I fully know why there's an issue and this is not the point of my question. The question is about how you name this particular multiple interface inheritance ambiguity, if there's a name for it.
For example, in C++, the ambiguity that arises when you use multiple implementation inheritance and cannot determine which overridden method to use is called the "diamond problem":
http://en.wikipedia.org/wiki/Diamond_problem
Now once again, I know this is not the same problem here: that's not the point. The point is that a name has been coined in that previous case.
And I'd like to know if a name exists for the issue I'm about to describe.
Here's an example of another kind of multiple inheritance, where one interface inherits from two other interfaces that have an incompatible method return type:
interface A {
void a();
Integer c();
}
interface B {
void b();
Long c();
}
interface MI extends A, B {...}
(notice multiple interface inheritance at work using the 'extends' keyword)
You cannot do that, because:
types A and B are incompatible; both
define c() but with unrelated return
type
Has a name been coined to describe that situation?
I'm not sure there is a specific name for it, or at least it doesn't seem to be very commonly used. It's "just" a problem of the implicit mapping of interface methods to class methods; if you could have overloads which differ in return types only, there would be no problem either. So it comes down to an signature/overloading/implicit method mapping problem.
In the "Thinking in Java" online book, there isn't a name for it either.
http://www.linuxtopia.org/online_books/programming_books/thinking_in_java/TIJ310_001.htm
Just a side-note, C# allows explicit interface implementations, which addresses this problem.
JLS ยง6.4.4, The Members of an Interface Type calls such duplicate superinterface members ambiguous, and requires a compile-time error. I was hoping for something colorful such as the Beaujolais Effect, Heisenbug, et al. Maybe two's-a-crowd?
I also don't know of any specific name for this problem. Whenever it arised it was described in a sentence containing the words return type incompatibility at some point. You could also call it the Map/Set incompatibilty as this is one of the more prominent and annoying examples in the Java class libraries. It makes it impossible to have the same class implement Map as well as Set or Collection just because Map defines a remove(Object) method with a different return type than Collection.
public interface Collection<E> extends Iterable<E> {
boolean remove(Object o);
}
public interface Set<E> extends Collection<E> {
}
public interface Map<K,V> {
V remove(Object key);
}
I'd hesitate to call this a multiple inheritance issue, because interfaces merely describe well, interface--a set of methods an implementing class must define--rather than any implementation. Extending an interface with other interfaces doesn't really mean the subinterface inherits from the superinterface, but rather that the subinterface is, in essence, a concatenation of the methods defined in the two.
If a third interface is used to extend the subinterface and provides a conflicting method declaration, it's essentially the same as if you had just provided the same two conflicting methods in the same interface.
I don't remember if I have ever seen any name for this. In Java Language Specification there is no name for this either.
The issue you describe exists in .NET as well as Java, but has a simple solution there: the .NET framework allows a class to implement an interface member using a class member with a different name. Thus, although the class methods which implement two interface members which differ only in return type are required to have different names, that does not preclude their ability to implement interface members with the same name.
If an interface inherits two interfaces with conflicting members, a class which implements the composite interface may implement the members just as if it had inherited the conflicting interfaces directly. Consumers of the combined interface will generally not be able to use the members of either component interface without a converting the reference to one of the other interface types, but the cast in question will be considered an upcast rather than an downcast.
The scheme implemented in .NET works nicely there. Unfortunately, there's no way to do anything similar in Java. I don't know that Java will squawk if an interface inherits other interfaces with conflicting members, but whether or not it squawks at that point, there would be no way to produce a class which could implement it.
I don't think a name has been defined because interfaces in Java cannot have method implementation, the problem is therefore avoided since there is always only one implementation to a specific method and hence no ambiguity will arise.
Have I missed the point or are you talking about the 'c' variable?