SubClass extends LinkedList<SuperClass> Properties - java

I'm working with superclass and subclass. My subclass extends the SuperClass this way:
public class SubClass extends LinkedList<SuperClass>
Does this mean that my subclass hold LinkedList properties. For example, if I'm creating objects of my subclass from other classes, am I able to do something like:
public class another {
private SubClass object;
public another(ArrayList<String> list) {
object = new SubClass();
SubClass localObject = object;
for (String elements : list) {
localObject.addAll(elements);
}
}
}
I want to add elements to end of the linked list.
Would this work? Or would I have to create add(), addAll() etc methods in the subclass in order for it to work?

SubClass inherits all the methods of LinkedList, but since it extends LinkedList<SuperClass> it can contain only objects of type SuperClass.
Your code at
for (String elements : list) {
localObject.addAll(elements);
has two problems.
The method addAll takes a Collection<? extends T>, which in your case is Collection<SuperClass> but you are passing in a single String.
Even if you modified it to pass in a collection of String it would still fail to compile. Only a Collection<SuperClass> is acceptable here.
If you changed it to
for (String element : list) {
localObject.add(element);
i.e. change to the add method instead of addAll, this is still wrong because the add() method in SubClass only takes objects of type SuperClass.

Jim Garrison is correct. But let me make it concrete.
The class called Float extends the class called Number
Integer is another class that also extends Number.
If you create a list of numbers (aka List<Number>) then you can put floating point numbers in that list, and you can put integers in that list.
The following code will compile cleanly.
List<Number> numberList = new LinkedList<Number>();
numberList.add(new Float(1.5));
numberList.add(new Integer(1));
You can not, however, add a potato to a list of numbers. Nor can you add a String, or any other type of object which is not a Number (or subclass of Number). The following code will generate the compile time error you cited.
list.add("this is a String.");
Getting back to your code now.
First let me say that when you extend List<SuperClass>, this gets you another List<SuperClass> with a different name, Subclass in this case. Which is to say SubClass is a list containing SuperClass objects. You could add some additional methods to your newly named class to differentiated it from List<SuperClass> but first and foremost it is just a list containing instances of SuperClass. I think you knew that already but I want to be clear.
Your method called another accepts an argument that is a list of strings (List<String>). So that means that every member of that list, is a String. But you are trying to pulls stuff out of that list (of strings) and then add it to a list of SuperClass. But the list of SuperClass can ONLY accept instances of SuperClass (whatever that is). So unless SuperClass happens to be a super class of String (and String only extends Object), then you will get an error.

Related

Java - Type vs instance type

When I do something like:
List<Integer> myList = new LinkedList<>();
Is the object "myList" of type List? I am more interested about the correct definition. Would it be correct to say that:
myLyst is of type List but its instance is of type LinkedList?
That doesn't make sense to me because the object can be only one type. So maybe it would be better to say that it is of type LinkedList but restricted to the interface List?
myList has a concrete runtime class, and that is LinkedList.
But LinkedList as a type, is a subtype of List, so it is also correct to say that myList is a List.
The thing that is definite at runtime is that an object has only one runtime class, which in this case is LinkedList. This class can be read by calling myList.getClass().
But checking type hierarchies, i.e., whether an object is an instance of a given type (class or interface), doesn't require that the type it's being checked against is a class. So:
myList instanceof LinkedList //true
myList instanceof List //true
myList instanceof Collection //true
myList instanceof ArrayList //false,
//because it's not an instance of ArrayList,
//and LinkedList is not a subtype of ArrayList
The LinkedList class implements the List interface. myList is an instance of the LinkedList class and is therefore of type LinkedList.
Since an interface is not a type, myList is not of type List, as List, an interface, is not a type.
I hope this answer should clear some things up?
Java List is an interface that extends Collection interface.Pic shows the hierarchy
Now, correct way would be, to say that "myList" is an interface variable currently holding the instance of LinkedList class.
You can look it from another analogy as well, interface is just an abstract representation therefore we can never create an object of type List thus it can only be used to hold reference of object of the class that implements it.
I would say that the static type of the variable is List and its runtime type is LinkedList.
This is obviously made possible by the fact that LinkedList implements List.
The distinction is important when discussing overriding (inheritance and virtual calls) and overloading (different methods with different parameters — parameters only take the static type into account)

How to remove two different Object having same class from List in java

What is best practice for removing two different Object having same class? List have Class file that create proxy by Factory.
List<? extends Class> listObject = new ArrayList();
...
Factory.createProxyObjectFromclassFile(List<? extends Class> list);
...
now I want to remove other Object from listObject like this:
removeMethod(Class<?> clazz){
listObject.remove(clazz.newInstance())
}
This is not possible because reference of Objects is not the same.
You need to override the Equals method of every object you insert so that it checks the class of the objct instead of the ref id
For example, you could have a superclass ForList with the overridden equals() method and insert only objects extending thag class.
If you want to any possible type of class, you may want to extend the List class with your own implementation so it will check on classes instead of using the default equals()
I don't know if I'm understanding your question correctly but if your list is composed of Class instances and you want to remove all instances of a certain class from the list, you should do something like:
private static void removeMethod(Class<?> clazz) {
listObject.removeAll(Collections.singleton(clazz));
}
Credits to this answer

implementing interface with generics java

I am writing some java code and I want to write methods in my main class Array. This class implements ImplementableClass. The former extends Iterable. The Array class has an type.
ImplementableClass.java:
public interface ImplementableClass<E> extends Iterable<E>{
public void insertObject(E obj);
public E removeObj(E obj);
}
Main.java:
public class Array<Integer> implements ImplementableClass<E>{
public void insertObject(E obj){
}
public E removeLastObject(E obj){
}
//... main method and others below...
}
I have some questions regarding the code in the two files above.
Reading the java documentation, Iterable is of type E (generic value). From what I understand, interfaces are just "blueprints" of the methods that MUST be used in the class that "implements" them. From a basic point of view, there shall not be any variables in here. With that being said, as you may see I am indeed declaring the methods in my ImplementableClass in Main as well. With that being said, I have a couple of questions:
When declaring my methods from ImplementableClass class in my Array class, this "overrides" the methods from my ImplementableClass class right?
Since "E obj" is the argument in both methods, do they have to be the same whenever I declare my methods in my Array class? What should I pass to the methods? What does "E obj" mean?
I want to create an array that can hold objects of type E. This means that whenever I instantiate a new object-> Array<Integer> theArray = new Array<Integer> I can call the methods I have on my Array class on theArray instance right? (i.e theArray.removeLastObject() ) What should I pass as an argument?
Why would Iterable<E> be of use in this case?
When declaring my methods from ImplementableClass class in my Array class, this "overrides" the methods from my ImplementableClass class right?
Yes (well, not technically since there's no functionality in an interface to override, but you can use #Override to indicate you're overriding it)
Since "E obj" is the argument in both methods, do they have to be the same whenever I declare my methods in my Array class? What should I pass to the methods? What does "E obj" mean?
They need to be the same as the generic type you've specified when you implement the interface. E obj means that you've declared a parameter called obj that is of generic type E. This means that you're required to define the methods to take that particular type as a parameter.
It would make more sense though, to define the generic type of your interface in the declaration, such as:
public class ArrayClass implements ImplementableClass<Integer>
so you can have methods like:
public void insertObject(Integer obj) {}
public Integer removeObj(Integer obj) {}
Or else you can make your Array class generic, and leave the specification of the generic type to the caller:
public class ArrayClass<E> implements ImplementableClass<E>
I want to create an array that can hold objects of type E. This means that whenever I instantiate a new object-> Array theArray = new Array I can call the methods I have on my Array class on theArray instance right? (i.e theArray.removeLastObject() ) What should I pass as an argument?
In order to do that, you would need to make your Array class generic, like shown above. The argument you pass in would be the same type you specify when you create the array (Integer in your example).
Why would Iterable be of use in this case?
Iterable is of use so you can make use of the iterator features of an array, and the enhanced foreach syntax (for (Object o : someObjectArray) {...})
Also, I would suggest not naming your Array class Array... and perhaps look at making use of already existing Iterable classes to construct what you're doing, but this looks like a learning exercise, so have at it.
HTH
What's actually happening is that you're implementing the interface, not overriding it. Since interfaces (in Java <= 7) don't have an implementation, there's nothing for you to really override. You can use the #Override annotation to indicate that you're implementing a method from an interface.
You whiffed on the generics in your second class. If you really want it to be generic (that is, it can be bound to any object), then you want this declaration:
public class Array<E> implements ImplementableClass<E>
That <E> is called a type parameter, and it's applied at the class level, meaning any non-static method or field in the class may make use of it.
E obj is stating that you are willing to accept whatever type of object comes in as an argument. If you declared Array<Integer> intArray = new Array<>();, then E obj would translate internally to Integer obj instead. There's a decent amount of complex operations related to generics; reading up on it would be best.
Be specific as to what kind of data structure you want to use. Arrays and generics do not mix well. If you're creating a generic object array (as in, E[] backingStore), then creating a generic array would be a consideration to take into account.
Honestly, I'd recommend you use a List instead.
Iterable means that the object you have can be iterated with an enhanced-for statement. Why you'd want to do this is subject to your discretion, but that's why you'd want to use that particular interface.

If I have an Subclass of ArrayList, Can I Iterate over its elements Without Calling super.iterator()?

Say, for example, that I have
public class Foo<Game> extends ArrayList<Game>{
}
and I want to iterate over its elements. I'm aware that I can use a for loop with an its iterator. But trying something like:
for(Game g : super)
does not seem to work. This is mysterious(at least to me) because super is a reference to an object of type ArrayList<Game> which should be able to be iterated over. Is there some syntax that I'm missing?
EDIT: I added the Foo type to the class declaration.
This is mysterious(at least to me) because super is a reference to an object of type ArrayList<Game> [...]
super is not an object. If you instantiate a class that inherits from another class, you don't get two objects (this and super), there is only the one instance. (Heck, it'd become unwieldy with deep inheritance hierarchies!) super allows you to access methods from the super class (again, not an object) and use them in your method implementations. Those super methods still execute in the context of the this object, but now that object is of a subclass type. That's perfectly fine though, and it's one of the foundations for polymorphism.
this is an object: it's an instance of Foo and, because Foo inherits from ArrayList<Game>, it is also an ArrayList<Game> and thus implements Iterable<Game>. Therefore, you can just iterate over this.
Thus, you're looking for:
for (Game g : this) { ... }

Only allow specific types in an ArrayList

Is there a way to subclass the ArrayList class to only allow objects of a specific class (or subclass thereof).
Specifically, I have a base class called RecordStatus and I need to create ArrayLists with objects based on this class.
I know it would be easy to create a class based on ArrayList<RecordStatus> but then, every time I retrieve an element from the array, I need to cast it to the original class.
Is there an easier way to do this?
Is there a way to subclass the ArrayList class to only allow objects
of a specific class (or subclass thereof). Specifically, I have a base
class called RecordStatus and I need to create ArrayLists with objects
based on this class.
That's exactly what the generic construct in Java allows you to do. Note that you don't have to cast the instances coming out of your ArrayList<RecordStatus> as long as all subclasses of RecordStatus have the same API. You only have to do that if the subclasses have different methods/fields. For example, if RecordStatus has a method setStatus, and so does a subclass, no casting is necessary, as the dynamic dispatch of Java's polymorphism will make sure the method that gets implemented is correct based on the type of the instance on which the method is invoked at runtime.
You shouldn't need to cast anything if you set up your types correctly. For example, this should work:
List<RecordStatus> myList = new ArrayList<RecordStatus>();
//Add values to the list
RecordStatus myRecordStatus = myList.get(0);
But if you really want to subclass ArrayList, you can do the following:
private class MyArrayList<R extends RecordStatus> extends ArrayList<R> {
...
}
ArrayList<? extends RecordStatus> is as close as you can get.
I've created arrayList without troubles using a line like this
List<RecordStatus> list = new ArrayList<RecordStatus>();
Try Collections.checkedList(List<E> list, Class<E> type). This will ensure the Type-Safety.

Categories

Resources