I would like to make a class extend another class among several like this:
class Special extends < Class1<type1> , Class2<Type2>> {
// ToDo
}
I tried something like:
class Special<T1, T2, T3, T4> extends < T1<T2> , T3<T4>> {
// ToDo
}
Of course that syntax does not compile. How can I do that?
EDIT 1
Let's be clear here: I do NOT want multiple inheritance. I would like my class to extend EITHER one super class, EITHER another one. For that I am asking if there is a possibility doing so using generics.
The same way one can use generics for this special map of array:
class MapArray<T_KEY, T_VALUE> extends LinkedHashMap<T_KEY, ArrayList<T_VALUE>> {
}
This code works an allows the user to put any type for T_KEY and T_VALUE.
I would like to know whether is would be possible to use generics with classes.
To put it more simply I would like to do that:
class Special extends < Either_this_class, Either_this_one > {
}
You can do (staying withing the limits of Java's syntax):
class SubAndImp extends Super implements Interface {
}
or
class ImpAndImp implements InterOne, InterTwo {
}
All or some of the extended and implemented types can be generic:
class SubAndImp<X,Y> extends Super<X> implements Interface<Y> {
}
or
class ImpAndImp<X,Y> implements InterOne<X>, InterTwo<Y> {
}
Your subclass can also stay out of being generic, by instantiating a generic parameter:
class SubAndImp extends Super<Integer> implements Interface<String> {
}
Java supports only multiple interface inheritance. So you cannot extend multiple classes but you can implement any number of interfaces.
Related
I have the following Java generics question
I have the following generic class thay may be sketched as:
public class MyClass<T> {
AnotherClass<T> another;
OtherClass<T> other;
...
}
where ... represents code that is not relevant to the case.
For the class MyClass<T> is not as important which exact type T is (as of now) but for both:
AnotherClass<T>
OtherClass<T>
is absolutely crucial what the generic type is and decisions will be made at runtime in base of that.
Based on that, the type T is not completely arbitrary, it may be either an instance of a hierarchy of classes T_1 or a hierarchy of classes T_2.
As is defined the class, the type T is equivalent to Object but I know that is equivalent to either T_1 or T_2
There is not businnes relation between entities T_1 and T_2 therefore I'm not doing:
public interface BaseT { ... }
public class T_1 implements BaseT { ... }
public class T_2 implements BaseT { ... }
public class MyClass<T extends BaseT>
Clarification about why using a generic if they are unrelated:
I'm defining (trying to) a generic class for both because even they are unrelated explictly, there is a implicit relation because both T_1 and T_2 can and will appear associated to the entity represented in MyClass
T will be the same for MyClass, AnotherClass and OtherClass so that in a instance there will only be either T_1 or T_2 but never both at the same time.
My question is, which alternatives do I have here other than design an
interface for MyClass and implement it for both T_1 and T_2?.
Can I achieve something like MyClass<T extends T_1 or T_2>?
Kind regards
Probably, this is not exactly what your're looking for, but you might give it a try:
Create an abstract generic class that implements everything:
public abstract class MyClass<T>
{
AnotherClass<T> another;
OtherClass<T> other;
// Add any code needed
}
Then create 2 generic classes for both base classes.
These classes may be empty if all code can be implemented in the abstract one:
public class MyT1Class<T extends T_1> extends MyClass<T>
{
}
public class MyT2Class<T extends T_2> extends MyClass<T>
{
}
I know it's not a very good answer but I couldn't leave it as a comment to the question.
You can check the type at runtime by trying the following:
public class MyClass<T>
{
// This factory-method creates an instance of the class if the correct type is passed
// It throws a RuntimeException if not.
public static <T> MyClass<T> getInstance(Class<T> type)
{
if (T_1.class.isAssignableFrom(type) || T_2.class.isAssignableFrom(type))
return (new MyClass<T>());
else
throw new RuntimeException("Cannot create instance of MyClass<" + type.getName() + ">");
}
...
}
Then
class T_3 extends T_2
{
}
....
MyClass<T_3> test_1;
test_1 = MyClass.getInstance(T_3.class); // This will succeed
MyClass<String> test_2;
test_2 = MyClass.getInstance(String.class); // Fails
I'm having difficulty using generics for a redesign/refactoring I'm doing on an existing design.
public interface DataDto {
// some data here
}
public interface SetDto<MyDataDto extends DataDto> {
List<MyDataDto> getData();
}
public interface Results<MySetDto extends SetDto<DataDto>> {
MySetDto getResults();
}
public interface MyProblemInterface<MyDataDto extends DataDto,
MySetDto extends SetDto<MyDataDto>,
MyResults extends Results<MySetDto>> {
// some stuff here
}
My problem is that I get the following error for MyProblemInterface:
Bound mismatch: The type MySetDto is not a valid substitute for the
bounded parameter <MySetDto extends SetDto<DataDto>> of the type
Results<MySetDto>
I admit my experience with generics is somewhat limited, but basically I'm trying to enforce that all three of the types in MyProblemInterface are the same "type". For example, if I have ADataDto, BDataDto, ASetDto<ADataDto>, BSetDto<BDataDto>, AResults<ASetDto>, BResults<BSetDto>, I want to ensure a class can't implement MyProblemInterface in a manner like AMyProblemInterface<ADataDto, ASetDto, BResults>. I would think that since MySetDto extends SetDto<MyDataDto> just fine, I could continue to take that further, but I'm apparently wrong.
Thank you for any help.
You want too much from Java generics.
It would be simpler to declare your interface as following:
public interface MyProblemInterface<MyDataDto extends DataDto>
And then force method to use SetDto<MyDataDto> and Results<MySetDto>.
By using generics in class/interface declaration you specify some kind of variety which is determined later in definition. But in your case you said that SetDto and Results will always have MyDataDto as parameter, so there is no variety.
Shouldn't it be something like this instead, and you add the actual classes only when implementing the interfaces.
Updated the code, because I forgot to add the right Results definition. This should work.
public interface DataDto {
// some data here
}
public interface SetDto<T extends DataDto> {
List<T> getData();
}
public interface Results<T extends SetDto<? extends DataDto>> {
T getResults();
}
public interface MyProblemInterface<T extends DataDto, E extends SetDto<T>, K extends Results<E>> {
// some stuff here
}
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 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 this question.
I have class UserImpl implements MyUser, YourUser
and class UsersGetterImpl implements MyUsersGetter, YourUsersGetter.
I want to implement a method inside UsersGetterImpl, which returns
List<MyUser> getUsers() for MyUsersGetterinterface, and
List<YourUser> getUsers() for YourUsersGetterinterface, but I cannot understand what have to be the return type of getUsers() inside the UsersGetterImpl class - probably it has to be something with wildcards (like List<? extends UserImpl> getUsers(), but not exactly, because this example won't work...)
It is hard to tell what you are asking, but according to the Java Language Specification:
In a situation such as this:
interface Fish { int getNumberOfScales(); }
interface StringBass { double getNumberOfScales(); }
class Bass implements Fish, StringBass {
// This declaration cannot be correct, no matter what type is used.
public ??? getNumberOfScales() { return 91; }
}
It is impossible to declare a method named getNumberOfScales with the same signature and return type as those of both the methods declared in interface Fish and in interface StringBass, because a class can have only one method with a given signature (ยง8.4). Therefore, it is impossible for a single class to implement both interface Fish and interface StringBass.
However, if both of your interfaces specify the same return type, then you can go ahead and implement that method. If MyUser and YourUser have a common ancestor then you could do List<? extends User> or if they have no commonality you can use simply use List<?>.
At that point though, you have to stop and consider if a common implementation is what you actually want. I suspect there may be a more elegant solution, if you provided us with more details about your problem.
Edit:
Based on your comment, you want something like...
interface MyUserGetter { List<? extends MyUser> getUsers(); }
interface YourUserGetter { List<? extends YourUser> getUsers(); }
class UserGetterImpl { List<? extends UserImpl> getUsers(); }
This is untested, and I'd guess has a 50% chance of working.
The architectural suggestion is that instead of having a single implementation for two interfaces you might actually want two implementations of one interface:
interface User {}
class MyUser implements User {}
class YourUser implements User {}
interface UserGetter { List<? extends User> getUsers(); }
The short answer is: it can't be done. You cannot have two methods whose signature differs only by return type, and you therefore cannot have one class implement two interfaces that define methods that only differ by return type.
The easy fix is to make MyUsersGetter and YourUsersGetter have methods with different names.
One possible workaround would be to have UsersGetterImpl not implement MyUsersGetter and YourUsersGetter directly, but to have delegates:
class UsersGetterImpl {
public MyUsersGetter getMyUsers () {
return new MyUsersGetter () {
public List<MyUsers> getUsers () {
//do stuff here
}
}
}