Why is declaring List implementation not needed? [duplicate] - java

This question already has answers here:
Type List vs type ArrayList in Java [duplicate]
(15 answers)
Closed 7 years ago.
I am using a method that returns type List<>, and I am then able to call methods on that List :
List<Artist> artists = artistsPager.artists.items;
artists.add(new Artist());
To be clear artistsPager.artists.items is returning type List<Artist>.
Since List is only an interface, how is the compiler letting me use this artists object, doesn't a List<> always need an implementation, like ArrayList?
For example, the compiler won't let me do the following, because "List is abstract; cannot be instantiated":
List<Integer> list = new List<Integer>();
How is artistsPager.artists.items any different than new List<Integer>()?
For those curious, this come from the Java Web API wrapper for Android. All help is greatly appreciated.
I do not believe this is a duplicate of this question because even though the answers are the same, the question that begets them is different. The other question is asking the difference between type List and ArrayList, whereas my question was wondering why the compiler was not complaining when the implementation of List was hidden.
I am fine with having this marked as a duplicate to direct future users to that question, but I do not think it should be closed as the answers here I think would be immensely helpful to other users.

How is artistsPager.artists.items any different than new List<Integer>()?
artistsPager.artists.items is a field of type List<>. Somewhere in the code, it must have been instantiated with a concrete implementation like ArrayList.
new List<Integer>() is a constructor call, which is invalid because List is an interface.

doesn't a List<> always need an implementation, like ArrayList<>?
Yes, you need an implementation in order to create an instance. However, the compiler knows two things:
It knows that you have already created some instance, and assigned it to items, and
It knows that whatever you have assigned to items, implements List<> interface
Knowing these two things is enough for the compiler to let you call add on a variable declared as an interface type. In this way your code does not need to care what implementation you get - an ArrayList<>, a LinkedList<>, or some custom implementation you developed: your code will work with all of them.
Note that the practice of referring to objects through their interface type is desirable. It is called programming to interface. It lets you hide implementation details, and swap objects for different implementations later on.

This means that a concrete list was created somewhere (for example, an ArrayList).
You only know that the list that is created is implementing methods from the List interface, allowing you to use these methods.
Take this example hiding the concrete LinkedList from the user:
public static List<Integer> makeListOfInts(){
return new LinkedList<Integer>(){
{
add(1);
add(2);
}
}
}
I can be easily replaced with an ArrayList:
public static List<Integer> makeListOfInts(){
return new ArrayList<Integer>(){
{
add(1);
add(2);
}
}
}
And all the function's user knows is that a List is returned, but it does not know the concrete type of the list. It may only use functions from the List interface, and not from the specific implementation that was selected.

Related

Relationship between ArrayList / ObservableList / List and Classes & Interfaces in General [duplicate]

This question already has answers here:
What does it mean to "program to an interface"?
(33 answers)
Closed 6 years ago.
I’m hoping to get some clarification on a topic which I find very confusing: The relationship between ArrayList / List / ObservableList, which also ties into the differences between Classes and Interfaces. I’ve read multiple texts on the subject, and the more I read, the more confused I become.
Here’s what I do know for certain: ArrayList is a Class, which means you can create as many ArrayList objects as you like. (This is good news for me, because I love working with them.) I’m also learning JavaFX, and there’s a lot of FX objects which take ObservableLists as input. But ObservableLists are Interfaces, not Classes, so forget about creating any ObservableList objects. At first, I assumed that ArrayList was a child class of List, and ObservableList is an Interface to List & any List child Classes. …But reading further, I see that List is actually an Interface, not a Class, and the parent Class of ArrayList is AbstractList. So that didn’t clear up a lot for me.
Another bit that is driving me crazy: In another forum post, a wiser coder gave me this snippet of code to help my ArrayLists accessible via the ObservableList interface:
List<myClass> myList = new ArrayList<myClass>();
While this method of declaring and initializing an ArrayList compiles and works great, I just plumb don’t understand what is going on here. I thought List was an Interface, not a Class, so how can I create a myList object of type List? If I had to guess, I’d suppose that there is an Interface named List and another, separate Class named List, and due to the context here, Java assumes I am referring to the Class.
On a side question, is there a recommended website or text that people could recommend I consult on this topic? I’ve read “Java in a Nutshell,” the Oracle website, different posts on this site, “Java for Dummies,” and “Java in a Nutshell Examples,” but no illumination yet. Any guidance on understanding this topic is wildly appreciated.
Many thanks!
-RAO
Brief (so brief) resume:
java.util.List is an Interface. That is, defines the contract that all clases implementing that interface should code (except abstract classes)
java.util.ArrayList is a class that implements that interface
As you can't instantiate any interface, you must use the implementing classes (f.i. ArrayList) but, you can manage that as an interface and no matter what is the real class behind it. You just know that your class implements all methods in the interface.
So,
List<myClass> myList = new ArrayList<myClass>();
Just means that you're instantiating a List (actually an ArrayList) and that means that you're going to manage that list through the methods defined in the java.util.List interface
Check this link for complete information about working with interfaces
If several books and articles haven't helped you, maybe a different perspective will. Let's take a look at the statement you've outlined:
List<myClass> myList = new ArrayList<myClass>();
You're not actually instantiating a List here. You're instantiating an ArrayList, and referencing that object with a reference of type List. This means that when you're working with myList, the compiler will treat the object as a List even though the Object it's referencing is an ArrayList. This line compiles because the compiler looks to the instantiation versus the reference type and says, "Yes, this ArrayList is a List, and so this is legal.(Doing this allows you to ensure type safety by always havingmyListconform to typeList, no matter what kind ofList` it references).
An ArrayList is a List because it implements the List interface. However, interfaces don't define their methods. So what happens when we do this?
myList.add(myObj);
Here's a simplified version of how it happens. The compiler looks at myList.add and says "Yes, myList is a List, and List has a method add, and so this code works." Well, List doesn't define how it works (the method is essentially abstract), so when this action is actually run, it looks to the type of list the object is, ArrayList, which tells the machine to add the object to the end of the list. And so it does. (This is also why you must define every method of an interface when implementing it.)
I can't say this story-form answer is completely accurate but it might help things click for you.

What's the point of setting object type as super class or interface in java [duplicate]

This question already has answers here:
"Program to an interface". What does it mean? [duplicate]
(8 answers)
Closed 8 years ago.
I've seen many times statements like this:
List list = new ArrayList<String>();
What's the point of writing like this? I mean setting the type of object a super class or implemented Interface of it. Is this makes a difference or improves performance or things like that?
Note
My English is poor and I've probably written the question title and body confusing. Please edit that and then remove this line.
That statement means that you can use all of the features of List that are implemented using ArrayList but you could also use the features inside LinkedList. Although there is no harm if you have the object type as ArrayList, it could be useful for example, if you have a method that takes in a List parameter instead of an ArrayList, your choices have expanded and you can have other classes that implement that type, e.g LinkedList.
To put it simply, if you are using the interface List as its type, you are saying: "I want to use any class that does these things to do my own" as List is an interface. But if you just use ArrayList, you are saying: "I want to use just this specific class to to my things". In summary, it gives you more flexibility.
Other than that, there isn't much of a difference using the super class as the type or using ArrayList or other subclass as itself.
Hope that this is what you are asking about, and hope that it makes sense. If not, feel free to ask any questions.

Why we should use Interface, instead of concrete types?

When using collections in Java, we are advised to use Interface instead of concrete types.
Like: List<Object> list = new ArrayList<Object>();
But, using ArrayList<Object> list = new ArrayList<Object>(); will also does the same job, right?
Yes, but if you later change your mind and use a LinkedList You have to change much more in your code.
That is the Polymorphism which is the core concept of OOP.
It means ‘a state of having many shapes’ or ‘the capacity to take on different forms’. When applied to OOP , it describes a language’s ability to process objects of various types and classes through a single, uniform interface.
List is a Uniform interface and its Different implementations are like ArrayList ,LinkedList.....etc
Prefer to read :What does it mean to program to a interface?
When you define your list as:
List myList = new ArrayList();
you can only call methods and reference members that belong to List class. If you define it as:
ArrayList myList = new ArrayList();
you'll be able to invoke ArrayList specific methods and use ArrayList specific members in addition to those inherited from List.
Nevertheless, when you call a method of a List class in the first example, which was overridden in ArrayList, then method from ArrayList will be called not the one in the List.
Also the first has the advantage that the implementation of the List can change (to a LinkedList for example), without affecting the rest of the code. This is will be difficult to do with an ArrayList, not only because you will need to change ArrayList to LinkedList everywhere, but also because you may have used ArrayList specific methods.
There's a useful principle: for declared types, use the loosest (vaguest) interface possible (and List is 'looser' than ArrayList).
In practice, this means if you only need to access methods declared in List<Object> on your list instance (which is actually an ArrayList), then declare it as List<Object>. This means you can change your mind on the exact type of list later and you only need to change the line that actually instantiates the ArrayList (or LinkedList or whatever you choose).
This has implications for method signature too: if you were passing around an ArrayList instead of a List, and then changed your mind about it being an ArrayList, you have to go and edit lots of method signatures.
Please read up on Polymorphism if you'd like to know more.
Tangentially related is the Liskov Substitution Principle:
What is the Liskov Substitution Principle?
Interfaces or should I say base calsses are used to generalize things and problems at hand. So when you implement an interface you can always get the specific objects.
For example:
From Animal interface or super class you can always derive specific interfaces or calsses like Lion, but not the other way, becaus its true that a Lion is an animal but several other animals cannot be derived from Lion. Thats why it is advised to make things general and hence use interfaces.
Same applies in your case. You can always get ArrayList and other implementations from a List.
Say you have a class with the following method
public ArrayList<T> foo (ArrayList<T> someInput) {
//Do some operations on someInput here...
return someOutput;
}
Now, what happens if you change the program so that it uses LinkedList objects instead of ArrayList objects? You will get a compiler error wherever this method is called, and you would have to go through and refactor your code so that it accepts LinkedList objects.
If you had programmed to an interface and used a List instead:
public List<T> foo (List<T> someInput) {
//Do some operations on someInput here....
return someOutput;
}
If this was the case, no refactoring would be necessary as both the LinkedList and ArrayList classes implement List so there would be no compiler errors. This makes it incredibly flexible. It does not matter to the method what it takes in and what it returns, as long as the objects implement the List interface. This allows you to define behaviour without exposing any of the underlying implementation.

Reason for - List list = new ArrayList(); [duplicate]

This question already has answers here:
Why do some people use the List base class to instantiate a new ArrayList?
(4 answers)
What does it mean to "program to an interface"?
(33 answers)
Closed 9 years ago.
I have seen code like this many times:
List<String> list = new ArrayList<String>();
Why do people take the parent of ArrayList (and other classes) instead of the type of the generated object?
Does that take less performance? Or why should someone do this?
When someone writes code like this, he/she is trying to follow a basic OO design principle which says -
Program to an interface, not to a concrete implementation
I have explained this principle in one of my blog posts. Look in the Class Inheritance VS Interface Inheritance section.
To summarize the post, when you use a reference of a parent type to refer to an instance of a sub-type, you get a lot of flexibility. For example, if you ever need to change your sub-type implementation in the future, you will be able to do that easily, without changing much of your code.
Consider the following method -
public void DoSomeStuff(Super s) {
s.someMethod();
}
and a call to this method -
DoSomeStuff(new Sub());
now, if you ever need to change the logic inside someMethod, you can easily do it by declaring a new subtype of Super, say NewSubType, and changing the logic inside that implementation. In this way, you will never have to touch other existing code which utilizes that method. You will still be able to use your DoSomeStuff method in the following way -
DoSomeStuff(new NewSubType());
Had you declared the parameter of DoSomeStuff to be of Sub, you would then have to change its implementation too -
DoSomeStuff(NewSubType s) {
s.someMethod();
}
and it may also chain/bubble to several other places.
In terms of your collection example, this lets you change the list implementation that a variable is pointing to without much hassle. You can easily use a LinkedList in place of an ArrayList.
When you write:
List<String> list = new ArrayList<String>();
Then you are sure you'll use only the functionality of the interface List. (ArrayList implements List, so List is more flexibl).
Using this, allows you to change the ArrayList to other types in the future (like LinkedList..).
It means you can swap out the type of list at any point with anything that implements the List interface, as opposed to creating a rigid model that can only use ArrayList. For example:
private List<String> list;
public SomeConstructor()
{
// At this point, you can make it any type of object you want.
list = new ArrayList<String>();
list = new LinkedList<String>();
list = new AttributeList<String>();
}
This will abstract your code that uses the list object, away from the details like what exact object type list is. All it needs to know is that it has the add method etc. This is called Loose Coupling.
To sort things out:
For more flexibility you initiate interface List:
So if you don't need all ArrayList use List only.
You can write something like: List<String> = Arrays.asList("aa", "bb","cc").
For sure, less functionality can help to performance. As you know If you want to use multithreaded application, use Vector instead but it will down your performance.
Took from here
Because a method doesn't have to know what list-implementation you use.
A Method just needs to know that is is a list.
The Method can still be used.
Always program to an interface, not to a concrete implementation. (In this case List)
Generally it is preferred to work with the Interface class (List in this case) so that any List implementation could later be substituted with minimal fuss if requirements change.
Although ArrayList possibly supports some methods that are not on the List interface, this declaration makes it clear that those extra methods are not relevant in that case.
List<String> list = new ArrayList<String>();
In collection framework List is an interface while ArrayList is implementation. Main reason you'd do this is to decouple your code from a specific implementation of the interface also this will be helpful in case if you wish to move to some other implementation of List in the future.

"Instantiating" a List in Java? [duplicate]

This question already has answers here:
How to initialize List<String> object in Java?
(13 answers)
Closed 8 years ago.
Trying to use the following code:
List<Integer> list = new List<Integer>();
I get the following error message:
java.util.List is abstract; cannot be instantiated
What does this mean and why can't I initialize a List the same way I would an ArrayList?
In Java, List is an interface. That is, it cannot be instantiated directly.
Instead you can use ArrayList which is an implementation of that interface that uses an array as its backing store (hence the name).
Since ArrayList is a kind of List, you can easily upcast it:
List<T> mylist = new ArrayList<T>();
This is in contrast with .NET, where, since version 2.0, List<T> is the default implementation of the IList<T> interface.
List is an interface, not a concrete class.
An interface is just a set of functions that a class can implement; it doesn't make any sense to instantiate an interface.
ArrayList is a concrete class that happens to implement this interface and all of the methods in it.
Use List<Integer> list = new ArrayList<Integer>();
List is the interface, not a class so it can't be instantiated. ArrayList is most likely what you're after:
ArrayList<Integer> list = new ArrayList<Integer>();
An interface in Java essentially defines a blueprint for the class - a class implementing an interface has to provide implementations of the methods the list defines. But the actual implementation is completely up to the implementing class, ArrayList in this case.
The JDK also provides LinkedList - an alternative implementation that again conforms to the list interface. It works very differently to the ArrayList underneath and as such it tends to be more efficient at adding / removing items half way through the list, but for the vast majority of use cases it's less efficient. And of course if you wanted to define your own implementation it's perfectly possible!
In short, you can't create a list because it's an interface containing no concrete code - that's the job of the classes that implement that list, of which ArrayList is the most used by far (and with good reason!)
It's also worth noting that in C# a List is a class, not an interface - that's IList. The same principle applies though, just with different names.
A List isn't a real thing in Java. It's an interface, a way of defining how an object is allowed to interact with other objects. As such, it can't ever be instantiated. An ArrayList is an implementation of the List interface, as is a linked list, and so on. Use those instead.
A List in java is an interface that defines certain qualities a "list" must have. Specific list implementations, such as ArrayList implement this interface and flesh out how the various methods are to work. What are you trying to accomplish with this list? Most likely, one of the built-in lists will work for you.

Categories

Resources