Is there possible to add a new custom method to the well-known interface List in a way in Java? I tried to implement List interface to "public abstract class MyList", however, I would like to achieve it remaining the same name of the interface "List". For example, later implememnt in the following way:
List mylist = new ArrayList();
mylist.newmethod();
No, Java does not support such a feature. Use composition.
You could extend it to another interface
interface MyList<E> extends List<E> {
//add new methods here
}
Here's what you want to do. I wouldn't recommend it though, it can be confusing to have two List classes.
public abstract class List implements java.util.List {
public void myMethod() {
...
}
}
Related
I am a C# programmer and have agreed to help a fried doing Java homework.
In one example I want to create a class that extends a generic List. In C# this looks like
public class MyListClass : List<MyCustomType>
I have tried
public class MyListClass extends List<MyCustomType>
and get the error "no interface expected here". Well, I am not trying to use an interface... Any hints?
java.util.List is a interface. You need to implement it not extend it.
public class MyListClass implements List<MyCustomType>{
}
You can't extend interface. You must implement it.
But you can extend one of implementations (LinkedList for example):
public class MyListClass extends LinkedList<MyCustomType> {
Java ain't C++, so forget all about standard templates.
What you probably want is just a typed List:
List<MyCustomType> myList = new ArrayList<MyCustomType>();
and that's all.
It would be unusual to have "extending a generic class" as a goal for an assignment. It is unusual in the real world too.
You need to declare a generic class / interface
public class MyListClass<T> implements List<T> { }
Or
public interface MyListInterface<T> extends List<T> { }
Or best of all
public class MyListClass<T> extends AbstractList<T> implements List<T> { }
I'm creating a complex data type.
It's an ArrayList (chapters) of ArrayLists (chapter).
However, there are two versions of the chapter, each with it's respected elements and data types.
How could I declare my complex data type so I could add one or another (to have, e.g., ArrayList(chapters) which contains (chapter_typeI,chapter_typeII,chapter_typeII,chapter_typeI,chapter_typeII, etc...)?
make an abstract class, from which the both type of chapters inherit, and then declare a list of this type.
public abstract class AbstractChapter {}
public class ChapterTypeOne extends AbstractChapter {}
public classs ChapterTypeTwo extends AbstractChapter {}
List<AbstractChapter> chapters = new ArrayList<AbstractChapter>;
The operations that you are going to call should be declared in the abstract class, and then overriden as necessary in the specific implementations.
It is always better to create List of types than actual object if you have clear hierarchy defined.
List<Type> list = new ArrayList<Type>();
Now Type can be your interface
interface Type {
void method();
}
Now you can have
SubType1 implements Type {
void method() {
// do something.
}
}
SubType2 implements Type {
void method() {
// do something.
}
}
Also you can use Abstract Skeletal pattern in which you can have class AbstractType with default implementation if required
The best way is to use inheritance to define an abstract class "Chapter", and derive the types of chapters from the abstract class.
You could have an abstract base class "Chapter", from which ChapterI and ChapterII gets inherited.
I just wonder what usage the following code has:
public class Sub extends java.util.ArrayList<String> {...}
There is no any compiling restriction on the generic constraint java.util.ArrayList<String>.
The compiler does place restrictions on other code based on the type parameter in this case.
This will compile
public class Sub extends java.util.ArrayList<String> {
void addTwice(String s) { this.add(s); this.add(s); }
}
but this will not
public class Sub extends java.util.ArrayList<String> {
void addTwice(Object x) { this.add(x); this.add(x); }
}
Let's say you were making an index for a book, but you don't know how many indices you will need. You could make a class BookIndex extends ArrayList<String> or if you want to get really picky: BookIndex extends ArrayList<IndexEntry>.
/e1
Also, when a one Class extends a generic Class like ArrayList<String> you can grab the String out from the generic declaration, unlike if you had a class ArrayList<T>. In ArrayList<T> you would never be able to figure out what the T is.
You can extend class ArrayList, but it is not something that you should normally do.
Only ever say "extends" when you can truthfully say "this class IS-A that class."
Remember, Its not a good practise to extend the standard classes
Why not use like this ?
public class Sub {
List<String> s = new ArrayList<String>();
// ..
// ...
}
If you do that you can add to the basic functionality of an ArrayList or even change its normal functionality.
For example, you can override the add() method so that it will only add emails to the list.
I have created the following interface
public interface ISolutionSpace {
public boolean isFeasible();
public boolean isSolution();
public Set<ISolutionSpace> generateChildren();
}
However, in the implementation of ISolutionSpace in a class called EightQueenSolutionSpace, I am going to return a set of EightQueenSolutionSpace instances, like the following stub:
#Override
public Set<ISolutionSpace> generateChildren() {
return new HashSet<EightQueenSolutionSpace>();
}
However this stub wont compile. What changes do I need to make?
EDIT: I tried 'HashSet' as well and had tried using the extends keyword. However since 'ISolutionSpace' is an interface and EightQueenSolutionSpace is an implementation(and not a subclass) of 'ISolutionSpace', it is still not working.
Two possibilities:
#Override
public Set<? extends ISolutionSpace> generateChildren() {
return new HashSet<EightQueenSolutionSpace>();
}
Or
#Override
public Set<ISolutionSpace> generateChildren() {
return new HashSet<ISolutionSpace>();
}
and simply add instances of EightQueenSolutionSpace to the set.
Mind you, inheritance and other object hierarchy features don't exactly work like expected in generics.
But it's not your only problem : you try to return an ArrayList as an implementation of Set, which can't work !
Concerning the generics part, when you write Set<ISolutionSpace>, you say to the compiler you want a collection of instances of ISolutionSpace, but not of possible subclasses of ISolutionSpace. To be allowed to use subclasses, you'll have to use ? extends ISolutionSpace, which precisely says "accept any subclass of ISolutionSpace".
So, to have a valid code, you'll have to change both your interface and your implementation.
Your interface should become
public interface ISolutionSpace {
public boolean isFeasible();
public boolean isSolution();
public Set<? extends ISolutionSpace> generateChildren();
}
And your implementation
#Override
public Set<? extends ISolutionSpace> generateChildren() {
//for()
return new HashSet<EightQueenSolutionSpace>();
}
return new HashSet<ISolutionSpace>();
All the references in the HashSet can point to EightQueenSolutionSpace instances, but the generic type should be ISolutionSpace.
Set and List are different types of collections.
You could either change your declaration to return a list, or change the return parameter class to an implementation of Set (HashSet, TreeSet...)
According to the Java API:
Interface Set
All Superinterfaces: Collection
All Known Subinterfaces: SortedSet All
Known Implementing Classes:
AbstractSet, HashSet, LinkedHashSet,
TreeSet
I think you have to replace Set with List:
Interface List
All Superinterfaces: Collection
All
Known Implementing Classes:
AbstractList, ArrayList, LinkedList,
Vector
Assuming the caller would in turn work with the generic ISolutionSpace interface rather than the specific EightQueenSolutionSpace, just change the generateChildren method to public Set<? extends ISolutionSpace> generateChildren()
All the types of collection in Java is like this:
Collection
├List
│ ├LinkedList
│ ├ArrayList
│ └Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
So it's obvious for this error. Try modify Set into List would solve this problem.
Hope this would help you.
I've been trying to extend the ArrayList class without much success. I want to extend it, and be able to parameterize it.
So normally you have something like
ArrayList<SomeObject> list = new ArrayList<SomeObject>();
I want
MyList<SomeObject> list = new MyList<SomeObject>();
Simply extending ArrayList doesn't work.
public class MyList extends ArrayList ...
The when I try to use it I get the error
The type MyList is not generic; it
cannot be parameterized with arguments
<SomeObject>
I've tried variations of
public class MyList extends ArrayList<Object>
public class MyList<SubObject> extends ArrayList<Object>
with no success, If I use the subobject behind the class name it appears to work, but hides methods in the subobject class for some reason.
Any thoughts or suggestions on how to get this working right are appreciated.
You need to specify a type for the ArrayList's type parameter. For generic type parameters, T is fairly common. Since the compiler doesn't know what a T is, you need to add a type parameter to MyList that can have the type passed in. Thus, you get:
public class MyList<T> extends ArrayList<T>
Additionally, you may want to consider implementing List and delegating to an ArrayList, rather than inheriting from ArrayList. "Favor object composition over class inheritance. [Design Patterns pg. 20]"
public class MyList<T>
extends ArrayList<T>
{
}
MyList<SomeObject> list = new MyList<SomeObject>();
or
public class MyList
extends ArrayList<SomeObject>
{
}
MyList list = new MyList();
You shouldn't extend ArrayList, extend AbstractList instead:
public class MyList<T> extends AbstractList<T> {
public int size() {...}
public T get(int index) {...}
}