This question already has answers here:
When do we use interface extends interface
(3 answers)
Closed 6 years ago.
I have a question about java's use of an interface. I initially thought we can only implement interfaces in a given class. But in this code example,
public interface InterW {
}
public interface InterX<T> {
}
public class ClassY {
}
public class ClassZ {
}
Why is this a valid answer?
public class ClassB<T extends InterX<ClassY>> extends ClassZ
implements InterW {
}
Can a type parameter extend an interface?
And why is this one wrong?
public class ClassE<T implements InterW> extends ClassZ {
}
Please see the Oracle Documentation on Bounded Type Parameters
Particularly -
To declare a bounded type parameter, list the type parameter's name, followed by the extends keyword, followed by its upper bound ..... Note that, in this context, extends is used in a general sense to mean either "extends" (as in classes) or "implements" (as in interfaces).
Can a interface be ever be extended?
An interface can only extends interface .In fact An interface can extends multiple interfaces.
public interface Interface4 extends Interface1 , Interface2 ,
Interface3 { // methods }
coming back to you second question
And why is this one wrong?
`public class ClassE<T implements InterW> extends ClassZ {
}`
As user2615897 mentioned
To declare a bounded type parameter, list the type parameter's name,
followed by the extends keyword, followed by its upper bound .....
Note that, in this context, extends is used in a general sense to mean
either "extends" (as in classes) or "implements" (as in interfaces).
As per JVM, in context of upper bound whether you use extends or implements both does the same thing. But JVN allows the syntax extends to avoid confusion
Related
This question already has answers here:
Self bounded generics
(2 answers)
Closed 1 year ago.
I just saw a class declaration in our codebase that looks like this:
public abstract class SomeClass<T extends SomeClass<T>> implements Cloneable {
...
}
After learning from a couple of tutorials on Java generics, now I understand stuff like SomeClass<T extends Comparable<T>.
However, SomeClass<T extends SomeClass<T>> still doesn't make sense to me. Apparently, T must derive from SomeClass<T>... but SomeClass has not been declared yet! What is happening here?
Any help is appreciated!
Most probably, inside the abstract class there something like this:
public abstract class SomeClass<T extends SomeClass<T>> implements Cloneable {
public abstract T someMethod(); //<-- variable return type should be the implementing class itself
public abstract int someOtherMethod(T someInstance); //<-- variable parameter type should be the implementing class itself
}
With such declaration, when you extend the class SomeClass with something concrete, let's say SomeConcreteClass, then you'll have:
public class SomeConcreteClass extends SomeClass<SomeConcreteClass> {
#Override
public SomeConcreteClass someMethod() {
//implementation that returns SomeConcreteClass
}
#Override
public int someOtherMethod(SomeConcreteClass instance) {
//implementation that takes in parameter this type of class
}
}
When you declare an abstract class like that, you basically ask to self-reference the child class in the parameter type.
Of course you may also use another child (it would still be inside bounds as long as it extends SomeClass), but it's a rare use case (I'll never seen it personally)
For example,
public interface Foo<T extends Blackness, S extends T & Whiteness> { }
Error: Type parameter cannot be followed by other bounds
T extends Blackness and S extends T so S inherently extends Blackness. The only other contingency is that S must also extends Whiteness. Because of this restriction, S must be an extension of T but also implement the functionality of Whiteness. Because of this, you will likely have to provide the type T. It's not possible for S to have multiple bounded types, which is why a sub-interface is required that implements both. What you're trying to do doesn't make logical sense. Refer to this.
public interface Foo<T extends Blackness, S extends BlackAndWhiteness<T>> {
}
public interface BlackAndWhiteness<T extends Blackness> extends Whiteness, Blackness {
}
interface Blackness {
}
interface Whiteness {
}
I am learning generic types in Java now. To restrict the type argument passed to the type parameter, we use the keyword "extends". It means to either "extends"(as in class) or "implements" (as in interfaces). I don't understand why it can't mean to "extends" the the interface?
Interface only extends another interface ... class implements the interface
the only class that extends the interface will be the abstract class
Yes, you can use an interface when specifying (what's the right term?) a generic type (I had to answer to post the code):
class MyGeneric<T extends MyBaseInterface> {
}
interface MyBaseInterface {
}
interface MySubInterface extends MyBaseInterface {
}
public class GenericsTest {
private MyGeneric<MySubInterface> x = new MyGeneric<>();
}
As I said in my comment above, in <T extends X> "extends" is just a way to require that T is a subtype of X (where X can be a class or an interface).
I've got problem in my code in Java. I have four(important) Classes:
public class RDOutput extends OutputType
public class RDAnalysis extends AnalysisProperties
Now I'm trying to make a method in Analysis properties:
public abstract void display(ArrayList<? extends OutputType> results);
The main problem list, the objects in the ArrayList will be different subtypes of OutputType. In my class RDAnalysis I try to make specific overriding:
public void display(ArrayList<RDOutput> results) {
but eclipse says: Name clash: The method display(ArrayList) of type RDAnalysis has the same erasure as display(ArrayList? extends OutputType) of type AnalysisProperties but does not override it
I'm not familiar with Java tricks, I tried searching in documentation and I didn't find any solution to this problem.
My question is: Is that trick that I'm doing (Basic type in abstract and Extended in final function) possible in Java (if yes, how can I do that?) or do I have to make some enum to solve this?
I suggest you to introduce generic parameter to your class and use it to parametrize your method:
public abstract class A<T extends OutputType> {
public abstract void display(ArrayList<T> results);
}
public class B extends A<RDOutput> {
public void display(ArrayList<RDOutput> results) {}
}
It's because your display doesn't cover every case of the abstract method. Maybe try something like this :
public class RDOutput extends OutputType {}
public class OutputType {}
public abstract class AnalysisProperties<T extends OutputType> {
public abstract void display(ArrayList<T> results);
}
public class RDAnalysis extends AnalysisProperties<RDOutput> {
#Override
public void display(final ArrayList<RDOutput> results) {
}
}
The problem is that you try to override a method while restricting possible parameters.
=> ArrayList<? extends OutputType> accepts more possible elements than ArrayList<RDOutput> since RDOutput extends OutputType.
You break the rule that says: the concerned subclass method has to encompass at least elements of superclass one and NEVER restrict them.
So compiler avoid to valid this override.
By the way, avoid to type your reference with concrete values like ArrayList.
What about a LinkedList passed as arguments? ... prefer a more generic relevant type like List.
Problem here is that, after type erasure comes into play, the signature of the two methods are undistinguishable: they have the same return type and they can both accept a ArrayList<RDOutput> but the first one (the generic one) can also accept any ArrayList<T extends OutputType>.
This mean that, although the JVM won't be able to choose which one to call at runtime if you pass an ArrayList<RDOutput>, at the same time your display method does not override the abstract one because your method only work for lists of RDOutput, so if you pass a List<T extends OutputType> with T != RDOutput your specific implementation doesn't accept it.
You should consider using a type parameter on the whole class as suggested in other answers, or accept the fact that you won't be able to use any RDOutput specific methods in your display method without a cast.
if a method is expecting ArrayList<? extends OutputType>
ArrayList<RDOutput> cannot be passed to it, as parent type allows any child class of OutputType in arraylist.
consider a code like this
AnalysisProperties properties = new RDAnalysis();
properties.display(arraylist consisting of any child class of OutputType); //this line will cause runtime problems
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is it possible to reference a nested generic parameter in java?
A quick question on Java generics if I may. Is there syntax for declaring a generic class-wide type that is NOT used as a generic parameter for instantiation. For example:
public class <U extends FooUType> BarType<T extends FooType<U>>{
public U getU(){return U;}
}
To create a BarType I want to write the following, which in itself contains U, but I don't want to have to specify U separately. So:
BarType<SomeT<FooUType>> instance
We get the type of U implicitly from the parameterized SomeT without having to specify U separately. As opposed to :
public class BarType<U extends FooUType, T extends FooType<U>>
which would require:
BarType<FooUType,SomeT<FooUType>>
I guess I'm looking for something akin to the same idea in methods:
public <U> boolean StupidMethod(String s){
...
}
I would rather not use <? extends FooUType> as this leads to problems with method return types inside the class that return <U extends FooUType> U.
Many thanks for the clarification!
As the comments said, this isn't possible.
I would rather not use <? extends FooUType> as this leads to problems with method return types inside the class that return <U extends FooUType> U.
So, here you're saying that some methods of the class return U... yet you don't want to have U as a type parameter. Well, you can't have it both ways. Either have this:
public class BarType<T extends FooType<U>, U extends FooUType>{
public U getU() { ... }
}
Or this:
public class BarType<T extends FooType<? extends FooUType>>{
public FooUType getU() { ... }
}
If it's just the noisy instantiation you're concerned with, you can use new BarType<> where applicable with Java 7. Without Java 7, declare a factory method so the callers can use type inference:
public static <T extends FooType<U>, U extends FooUType> BarType<T, U> make() {
return new BarType<T, U>();
}
Thanks all,
I went for a different solution in the end. Basically the class I was trying to hide the U in was abstract and so I added U as a generic parameter as there is no way round this. I then created the concrete classes that extend this and had them fill in the type of U silently so that the caller wouldn't need to bloat their code.
Something like this:
public abstract class MyAbsClass<U extends Foo, T extends Bar<U>>{...}
public class ConcreteClass<T extends SomeBar> extends MyAbsClass<SilentUType, T>
where SomeBar is not parameterized. The user can then just instantiate with T:
new ConcreteClass<SomeDerivedBar>()
This worked for my scenario neatly, so I hope it helps others.