Hello StackOverflowers.
This is almost certainly a very basic question regarding object instantiation but in the following code sample:
List myList = new LinkedList();
Is this a form of inheritance? In other words, would one read this has LinkedList "is a" List and therefore inherits the methods defined in the List class? If so, provided a user constructed two classes of his or her own and used the same syntax as above, would the answer be the same?
Thanks all.
Caitlin
Is this a form of inheritance?
No.
would one read this has LinkedList "is a" List
Yes.
and therefore inherits the methods defined in the List class?
No. List is an interface and therefore cannot be extended/inherited (only implemented). But LinkedList still passes as IS-A because it implements all the methods required by the List interface.
If a user constructed two classes of his or her own with one being the base class and the other derived from it then yes it would be inheritance. But, the following
BaseType base = new SubType();
doesn't exactly demonstrate inheritance but polymorphism made possible by inheritance i.e. since the sub type IS-A base type as well it can be assigned to a base type reference.
Not quite, because List is an interface which LinkedList implements, not a superclass of LinkedList. You should read up on interfaces. There is no inheritance of List's methods - instead, there is simply a requirement that LinkedList has the methods listed in the List interface.
There is a principle that says "Always program to the interface not the implementation". LinkedList is an implementation of the List interface. That is, List simply specifies what a List can do but does not say how it does it.
The LinkedList class "obeys" the specification of a List and as such when we write programs we can depend on the LinkedList behaving exactly the way the List specified. This makes for more robust programs because if you decided to use another type of List, say an ArrayList, then your program code does not change because you did not depend on the implementation details of the List.
When you declare a variable as in
List myList;
The List type is referred to as the "apparent" type. That is, the compiler will treat myList as a List in the rest of your code. You cannot refer to any feature of myList that is not part of the List specification (without casting and breaking the principle).
When you instantiate the object as in
= new LinkedList();
the LinkedList type is known as the "actual type". The compiler does not care about this so much. It only matters at run time.
Related
This question already has answers here:
What does it mean to "program to an interface"?
(33 answers)
Closed 3 years ago.
So, according to GeeksForGeeks, an interface may have fields and method signatures, but those methods cannot be defined.
A class that implements an interface must then define the body of every method in the interface it implements.
If this is the case, what is the point of the method signatures in the interface? Why not allow oneself wiggle room rather than restricting yourself to have to define methods that you may or may not want to use?
Well, there are two points in that.
First, Java supports an implementation in interfaces. You need to use the default keyword, which is in Java since Java 9 (I am not quite sure about the version number). But, why would you do that?
Interfaces share a common interface for several classes and can therefor be used as data types. You can for example write a method, which needs a parameter of an interface type. Within the method you can then call all the parameters methods, where you know their signature, based on the interface.
The point here is, that interfaces describe common behavior. That is, what interfaces are for!
The difference between (abstract) classes and interfaces is: in (abstract) classes, you define, what you have and what it will look like. Inheritance in this case then is a relation of extension (or spezialization), so you describe it in form of the child IS a parent, but it may have something more. But the IS relation is the basic point.
Interfaces describe the behavior, so a class that implements a interface acts like that interface. LinkedList and ArrayList are quite good examples. Internally they look quite different, but they both store many elements (as hash lists do too). Both classes implement the List interface, because you can both treat them as lists: you can for example iterate over them, which is not the case in hash maps.
Thus, if you want to share common structure and content, use inheritance and maybe abstract classes to group them. If you want to share common behavior, use interfaces, because it doesn't matter, how they look inside, but what you can do with them. So you group it by action.
That's not always true. You can provide a default implementation in the interface:
interface SomeInterface {
default int combine(int a, int b) { return a + b; }
}
Now the method implementing SomeInterface can override combine method, but it doesn't have to. In that case it falls back to the default implementation.
Defining methods in the interface allows you to get all benefits of polymorphism. For example, if you have a List, you don't know what exact implementation of List was used to create it - whether it's ArrayList or LinkedList or something else, but you know that you can, for example, add elements in it and get elements from it, because methods add and get are defined in the List interface.
This question already has answers here:
Java ArrayList of ? extends Interface
(4 answers)
Closed 6 years ago.
I have many classes that implement an interface.
Can I have Stacks, Queues and ArrayLists defined like this?
ArrayList<Class<? extends BaseClass>>
to store objects ? In my scenario each object will be from a different class in the Stack, or ArrayList?
What are the pros and cons of such an implementation?
I am new to Java and hence this question. Any alternate recommendation to this?
Yes, you can.
The pros are that you can store various types of objects and be assured they implement the same contract and therefore can treat them polymorphically. You wouldn't be able to store them otherwise in the single structure without using Object; assuming no other commonality exists.
The cons are that you won't know, without additional checks, their type and therefore are limited to the functionality provided by that interface. You'd then me stuck doing the check for the instance type followed by a cast in order to use the uncommon functionality.
I have many classes that implement an interface
If BaseClass is that interface and you wish to store any sub type of BaseClass in ArrayList or Stack, declaration ArrayList<Class<? extends BaseClass>> is wrong for that purpose. It would simply be like,
List<BaseClass> arrList = new ArrayList<BaseClass>();
Can I have Stacks , Queues and ArrayLists defined like this?
Yes, you can define ArrayList or Stack on base type interface and put in Objects of concrete sub classes.
In my scenario each object will be from a different class in the
Stack, or ArrayList?
Yes, if you have inserted so. You are allowed to insert any sub type of BaseClass in that ArrayList so if you have put such elements , those will be there.
What are the pros and cons of such an implementation?
These would be same as already listed in ChiefTwoPencils's answer - that you have liberty to store various types of Objects in one List but when you retrieve objects from list to work on, you might have to check their type etc ( if interested in some that sub type's specific behavior ).
Hope it helps !!
Generally we use code to interface :
List<String> list = new ArrayList<String>();
Can we write the following?
AbstractList<String> list = new ArrayList<String>();
What will be the disadvantage of this particular initialization? Any insights will be appreciated.
Defining the list to be an AbstractList would tie your implementation to sub-classes of AbstractList, while using the List interface allows you to assign to the list variable arbitrary implementations of that interface.
Defining the list as AbstractList will also give you access (with no need for casting) to the methods of AbstractList which are not part of the List interface, but using them would make your code less flexible.
If you don't have a very good reason to do it, don't do it.
The main disadvantage is the general one: in Java, you can only inherit from one class at a time, while you can implement as many interfaces as you like.
If list is a private or local variable, there's virtually no advantage initializing as an interface. You'd be better of with
ArrayList<String> list = new ArrayList<String>();
However, if you have a public field or a method parameter, you'd be better off with the least specific declaration: the interface. The abstract class also implements the interface, so it can be used. But the consumer of your class can then use any class that implements the interface, while this class can inherit from any other class they might like.
The advantage of using List<String> over AbstractList<String> is that List specifies a contract, and AbstractList specifies a (partial) implementation. Using List ensures that your code is compatible with any implementation of List, rather than just those derived from AbstractList.
While following this practice might not seem like that big a deal with it comes to variable declarations, following this usage through out your code ensure greater flexibility throughout your application.
One disadvantage of using AbstractList like that is that you are limiting yourself to using list classes that extend AbstractList. It is quite possible to implement the List interface without having AbstractList as a superclass.
A second disadvantage is that this won't compile:
List<String> list = new ArrayList<String>();
AbstractList<String> list2 = list;
The Java type system won't let you assume that every List<String> is an AbstractList<String>.
List<String> someName = new ArrayList<String>();
ArrayList<String> someName = new ArrayList<String>();
Does it impact anything on performance?
The first one is a List of Objects and the latter one is ArrayList of Objects. Correct me if i am wrong. I got confused because ArrayList implements List Interface.
Why do people declare like this? Does it help in any situtions.
When i am receiving some email address from DB, what is the best way to collect it? List of eMail address Objects????
Finally one unrelated question.... can an interface have two method names with same name and signature and same name with different signature.
The difference between the declarations is more one of style. It is preferable to declare variables using the abstract, rather than the concrete implementation, because you can change the implementation choice later without changing the variable type. For example, you might change the List to use a LinkedList instead.
If you always use the abstract type (interface or abstract class) wherever you can, especially in method signatures, the client code is free to use whatever implementation they prefer. This makes the code more flexible and easier to maintain.
This is true even of variable declarations. Consider this:
public abstract class MyListUsingClass {
private List<String> list;
protected MyListUsingClass(List<String> list) {
this.list = list;
}
...
}
If the variable list was declared as ArrayList, then only ArrayLists would be accepted in the constructor. This would be a poor choice: Always try to let the client code chose the implementations they want to use.
Regarding you last question: Interfaces have the same restrictions for methods as classes do, so yes you can overload methods.
There is no performance impact, because in runtime you are dealing with the same class (ArrayList) in both cases.
They are both lists of Strings. The difference is that the first one is declared as a List but initialized as an ArrayList, which is a more specific type of List.
One instance where it helps is when you use an IDE with context-sensitive suggestions (Eclipse, NetBeans, etc). In the first case, whenever you use the suggestion feature, you will only see the members of the List interface. In the second, you will see all (public) members of ArrayList. In any given programming situation, as long as the more abstract type provides the functionality you need, you want to use that because it makes your code more robust: the more abstract a type is, the less likely it is to change in some future release of the API.
The best way to represent anything always depends on what you intend to use the data for and how much of it there is. Probably a List or a Set of javax.mail.internet.InternetAddress will fit the bill.
An interface can have two methods with the same name only if they have different parameter type signatures. Two methods which both take a single string cannot have the same name even if the parameters have different names, nor can you have two methods with the same name which differ only in return type.
In the first cause you're declaring a var of type list and using an ArrayList as its implementation.
In the second case you're declaring and defining an array list.
The difference is that, using the interface type (as in the first case), you will access only those methods defined in the List interface, and if ArrayList has some specific implementation methods, in order to access them you will need to cast your list to its sub-type (ArrayList).
In the second case, you're using a more specific type, so no cast is needed at all.
Performance - probably not.
Actually they are lists of Strings, not objects. Interfaces is not the point of what is held in Collection
Defining variable of superclass type could be usefull if you would like to make your code independent of concrete list implementation. If someday you would like to change list to LinkedList implementation - this won't be so harmful to all your code
Create new type EMail and store them into some kind of list (e.g. mentioned LinkedList or ArrayList) or just array (EMail[]). If you provide more information - this could be helpful.
edit
2. In both cases they are ArrayList of Strings. The difference is, that in first case you're doing casting to the superclass (losing access to some methods specific to ArrayList)
Does it impact anything on performance? No measurable impact. Your code will be the source of your performance issues, not nano-optimizations like this.
The first one ie s a List of Objects and the latter one is ArrayList of Objects. Correct me if i am wrong. I got confused because ArrayList implements List Interface. Exactly. You can assign a class reference to any of the types that it implements.
Why do people declare like this? Does it help in any situations.The reason you might want to is in case you want to change your implementation to use another concrete class that implements List e.g. LinkedList.
When i am receiving some email address from DB, what is the best way to collect it? List of eMail address Objects? Define "best". Depends on how you'll use them. Strings might be sufficient; perhaps a better abstraction would work for you.
Finally one un related question.... can an interface have two method names with same name and signature and same name with different signature. Interfaces define signatures, not implementation. You can have two interfaces with methods that define the same signature, but there can only be one implementation when you execute. If you have a Cowboy and Artist interfaces, both with void draw() methods, the class that implements both will have to decide what the single implementation will be. There can't be one for Cowboy and another for Artist, because interfaces don't have any notion of implementation.
public class SomeClass {
private HashSet<SomeObject> contents = new HashSet<SomeObject>();
private Set<SomeObject> contents2 = new HashSet<SomeObject>();
}
What's the difference? In the end they are both a HashSet isn't it? The second one looks just wrong to me, but I have seen it frequently used, accepted and working.
Set is an interface, and HashSet is a class that implements the Set interface.
Declaring the variable as type HashSet means that no other implementation of Set may be used. You may want this if you need specific functionality of HashSet.
If you do not need any specific functionality from HashSet, it is better to declare the variable as type Set. This leaves the exact implementation open to change later. You may find that for the data you are using, a different implementation works better. By using the interface, you can make this change later if needed.
You can see more details here: When should I use an interface in java?
Set is a collection interface that HashSet implements.
The second option is usually the ideal choice as it's more generic.
Since the HashSet class implements the Set interface, its legal to assign a HashSet to a Set variable. You could not go the other way however (assign a Set to a more specific HashSet variable).
Set is an interface that HashSet implements, so if you do this:
Set<E> mySet = new HashSet<E>();
You will still have access to the functionality of HashSet, but you also have the flexibility to replace the concrete instance with an instance of another Set class in the future, such as LinkedHashSet or TreeSet, or another implementation.
The first method uses a concrete class, allowing you to replace the class with an instance of itself or a subclass, but with less flexibility. For example, TreeSet could not be used if your variable type was HashSet.
This is Item 52 from Joshua Bloch's Effective Java, 2nd Edition.
Refer to Objects by their interfaces
... You should favor the use of interfaces rather than classes to refer to objects. If appropriate interface types exist, then parameters, return values, variables, and fields should all be declared using interface types. The only time you really need to refer to an object's class is when you're creating it with a constructor...
// Usually Good - uses interface as type
List<T> tlist = new Vector<T>();
// Typically Bad - uses concrete class as type!
Vector<T> vec = new Vector<T>();
This practice does carry some caveats - if the implementation you want has special behavior not guaranteed by the generic interface, then you have to document your requirements accordingly.
For example, Vector<T> is synchronized, whereas ArrayList<T> (also an implementer of List<T>) does not, so if you required synchronized containers in your design (or not), you would need to document that.
One thing worth to mention, is that interface vs. concrete class rule is most important for types exposed in API, eg. method parameter or return type. For private fields and variables it only ensures you aren't using any methods from concrete implementation (i.e. HashSet), but then it's private, so doesn't really matter.
Another thing is that adding another type reference will slightly increase size of your compiled class. Most people won't care, but these things adds up.