Generics and inheritance with bounds - java

In following code:
class BaseT {}
class Base<T extends BaseT> {}
class CLass1T extends BaseT {}
class Class1<T extends Class1T> extends Base<T> {}
I would like:
a) class Class1 should inherit class Base and parameter in bounds should be passed to class Base (It is done in this code)
b) Class1 should have parameter Class1T in their code, not T. Something like this:
class Class1<T> extends Base<Class1T> {}
c) Class1 should be opened to inheritance. Example:
class CLass2T extends CLass1T {}
class Class2 extends CLass1<Class2T> {}
How to do this? Is it possible?

This is your solution. If I understand correctly your requirement "open for inheritance".
class Class1<T extends Class1T> extends Base<T> {}

Related

Better adjustment to make class inherit different superclass

I have a class A that inherit Middle, which inherit OriginBase
public abstract class Base<T>
public class OriginBase<T extends CustomObject> extends Base<T>
public class Middle<T extends CustomObject> extends OriginBase<T>
public class A extends Middle<ObjectA>
public class B extends Middle<ObjectB>
public class C extends Middle<ObjectC>
Due to new feature and refactor of class A, I got a new version of class OriginBase, NewBase, which is similar to OriginBase and only have a few more methods. The problem is that not only class A inherit Middle, so I cannot simply change Middle's superclass to NewBase.
For now, my solution is to create a new class NewMiddle extends NewBase, add corresponding new override methods, and then make class A extends NewMiddle. But this will cause hundreds of lines of code duplication.
To avoid such redundant duplication, I have thought about generics inherit.
The idea is to let class A, B, C specify the Base class they needed, such as:
public abstract class Base<T>
public class OriginBase<T extends CustomObject> extends Base<T>
public class NewBase<T extends CustomObject> extends Base<T>
public abstract class CommonBase<B extends Base>
// I'm not sure is this a good idea, even not sure if it's a right concept...
public class NewMiddle<B extends Base<T extends CustomObject>, T> extends CommonBase<B, T>
// modified class
public class A extends Middle<NewBase<ObjectA>>
// other classes
public class B extends Middle<OriginBase<ObjectB>>
public class C extends Middle<OriginBase<ObjectC>>
How to achieve this kind of inheritance? Is this a good idea to do so?

java - Create a Comparator for a type that contains type parameters

I have a class defined as MyClass<T, S> for which I'd like to create a Comparator for MyClass where T and S extend Foo.
How can I go about doing this?
Unsuccessful attempts:
// Warning: The type parameter MyClass is hiding the type MyClass<T,S>
public class MyComparator<MyClass> implements Comparator<MyClass>
// Syntax errors and the warning from above
public class MyComparator<MyClass<T, S>> implements Comparator<MyClass<T, S>>
// Syntax errors
public class MyComparator<MyClass<T extends Foo, S extends Foo>> implements Comparator<MyClass<T extends Foo, S extends Foo>>
// Syntax errors and the warning from above
public class MyComparator<MyClass<? extends Foo, ? extends Foo>> implements Comparator<MyClass<? extends Foo, ? extends Foo>>
And various combinations of the above. What is the correct way? Thank you.
Your class is not generic. It always compares the same type of objects, ans this type is MyClass<? extends Foo, ? extends Foo>.
So it should be
public class MyComparator implements Comparator<MyClass<? extends Foo, ? extends Foo>>

Java generics: Bound mismatch.Looking for the valid substitute

I have a couple of generic classes:
public interface Data<E> {}
public interface Clonable<E extends Clonable<E>> {}
public interface NaturalNumberInterface extends Data<NaturalNumberInterface> {}
public class NaturalNumber implements NaturalNumberInterface {}
public interface SetInterface<E extends Data<E>> extends Clonable<SetInterface<E>> {}
public class Set<E extends Data<E>> implements SetInterface<E> {}
When I'm trying to create the new instance of Set Set<NaturalNumber> s=new Set<NaturalNumber>(); compiler says:
NaturalNumber is not valid substitute for the type parameter <E extends Data<E>> of the type Set<E>
Maybe you can help me to find the mistake, cause I spent a long time and didn't find the solution.
I assume that your SetInterface is defined in the same way as ListInterface and Data is just interface Data<T>.
The generic argument of SetInterface is F-bounded: E extends Data<E>. In your current code NaturalNumber type extends Data<NaturalNumberInterface>. So if E is NaturalNumber, then condition is violated as it should extend more specific type Data<NaturalNumber>.
You should use F-bounds for NaturalNumberInterface as well:
public interface NaturalNumberInterface<T extends NaturalNumberInterface<T>> extends Data<T>
public class NaturalNumber implements NaturalNumberInterface<NaturalNumber>
This way it will work.

Extend abstract generic class with abstract class in Java

I have a base abstract class public abstract class BaseModel <T extends BaseModel<T>>. Normally, I extend this class with something like public class OtherModel extends BaseModel<OtherModel>. For some of my classes, I want to have an intermediate abstract class, such that A extends B extends BaseModel.
I'd like to be able to declare public class EndModel extends MiddleModel<EndModel>. The only way I've managed to get Eclipse to be happy is if I declare MiddleModel as public abstract class MiddleModel<T extends BaseModel<T>> extends BaseModel<T>, but this seems ugly, and now I have to add a type anywhere I declare a variable as MiddleModel, even if I don't actually care what type it is. Is there a better way to do this?
If you want to add more functionality in MiddleModel, which depends on the generic type of it, declare it like this:
public abstract class BaseModel <T extends BaseModel<T>> {}
public abstract class MiddleModel <T extends MiddleModel<T>> extends BaseModel<T> {}
public class EndModel extends MiddleModel<EndModel> {}
Note that EndModel doesn't support that extensibility. It's a trade-off, because I don't want to write new EndModel<EndModel>() but rather new EndModel().

Java subclassing issue with generic type of self-referential type

import java.util.*;
// Let's define a self-referential type:
class SelfReferential<T extends SelfReferential<T>> {}
//A complete (i.e. not parameterized) subtype of SelfReferential:
class SubclassA extends SelfReferential<SubclassA> {}
//A partial (i.e. parameterized) subtype of SelfReferential:
class SubclassB<T extends SubclassB<T>> extends SelfReferential<T> {}
//Two complete subtypes of SubclassB
class SubclassB1 extends SubclassB<SubclassB1> {}
class SubclassB2 extends SubclassB<SubclassB2> {}
//Now let's define a generic type over SelfReferential:
class Generic<T extends SelfReferential<T>> {}
//No problem creating a subtype for A, B1 or B2
class GenericA extends Generic<SubclassA> {}
class GenericB1 extends Generic<SubclassB1> {}
class GenericB2 extends Generic<SubclassB2> {}
//We can also defined a parameterize type for specific types extending SubclassB
class GenericB<T extends SubclassB<T>> extends Generic<T> {}
//However, it does not seem possible to define a non-parameterized subtype of Generic of ANY subtype of SublassB
//My goal is to provide a type alias for GenericB<? extends SubclassB<?>> to avoid
//having to mention it everywhere in the code. This is like providing an alias for ArrayList<String> using
class ArrayListOfString extends ArrayList<String> {}
//Unsucessful attempts:
//class GenericAnyB extends Generic<SubclassB> {} //ERROR: bound mismatch
//class GenericAnyB extends Generic<SubclassB<?>> {} //ERROR: bound mismatch
//class GenericAnyB extends Generic<? extends SubclassB<?>> {} //ERROR: invalid syntax: a supertype cannot specify any wildcard
//class GenericAnyB extends Generic<SubclassB<? extends SubclassB>> {} //ERROR: bound mismatch
//class GenericAnyB extends Generic<SubclassB<SubclassB<SubclassB<SubclassB<SubclassB<SubclassB>>>>>> {} // well...
//class GenericAnyB extends <T extends SubclassB<T>> Generic<T> {} //ERROR: this syntax is illegal
Bottom line, I can't specify the "reference cycle" in the extends clause.
Question: Is this a Java language limitation?
You're right that this isn't possible, just like declaring a variable with a self referencing type is impossible without wildcards or raw types. You wouldn't be able to directly instantiate a SubclassB for the same reason that you can't use it as a bound without a self-referencing type parameter.
See this post for more discussion on this limitation: Self bound generic type with fluent interface and inheritance
The bottom line is that GenericAnyB would need to be generic itself to use SubclassB as a bound:
class GenericAnyB<T extends SubclassB<T>> extends Generic<T> { }
Which just adds an extra step in the hierarchy before anything is usable:
class GenericB1 extends GenericAnyB<SubclassB1> { }
class GenericB2 extends GenericAnyB<SubclassB2> { }

Categories