Extend abstract generic class with abstract class in Java - 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().

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 Generics: Class that takes a class that takes another class

I have a class BatchConfigurable
public class BatchConfigurable<T extends BatchContext>() {}
I am trying to write a wrapper for it. This will be another class that takes this class or any class that extends BatchConfigurable as parameter. For the declaration, I'm trying:
public class WrappedBatchConfigurable<E extends BatchConfigurable <T extends BatchContext>>() {}
This is invalid but as should be clear from the code, I want to preserve the property that the subtype of BatchConfigurable that WrappedBatchConfigurable takes should take a type that extends BatchContext as parameter. What would the syntax for this be?
You need to declare your type parameter T before you use it.
class WrappedBatchConfigurable<T extends BatchContext, E extends BatchConfigurable<T>> {}

Raw Type warning extending a Generic Class

I'm confused by the scenario described below where I am extending a generic class. The class I am extending is below:
public abstract class PresenterWidget<V extends View> extends HandlerContainerImpl
...
At first, I had this working (warning free) using the child class below:
public abstract class SideBarPresenter<V extends SideBarPresenter.MyView> extends PresenterWidget<SideBarPresenter.MyView> {
interface MyView extends View {
void doSomething();
}
...
But I want to convert MyView to an abstract class so I can implement a method. The way I think it makes sense is below.
public abstract class SideBarPresenter<V extends SideBarPresenter.MyView> extends PresenterWidget<SideBarPresenter.MyView> {
abstract class MyView implements View {
void doSomething() {}
}
...
The problem is this produces 2 warnings, both stating:
SideBarPresenter.MyView is a raw type. References to generic type
SideBarPresenter.MyView should be parameterized
Should I just ignore this warning or is there a better way to do this?
You should make MyView a static class. Otherwise its actually an inner class of a SideBarPresenter instance and that's probably where your generics warning is coming in. Inner interfaces are static by default.

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.

How to extend a generic class with added constraints in java?

I want to extend my BinaryTree class so that only Integer parameters are accepted and I can reuse the code.
public class BinaryTree<T extends Comparable<T>>
{/*code omitted for convenience*/}
public class BinaryTreeInt<T extends Integer> extends BinaryTree<T>
{/*code omitted for convenience*/}
I get following error on compilation-
BinaryTreeInt.java:1: type parameter T is not within its bound
public class BinaryTreeInt<T extends Integer> extends BinaryTree<T>
^
1 error
Can someone guide how to write code for such inheritance?
Integer is final so what you have is
public class BinaryTreeInt extends BinaryTree<Integer>
However the type implies its is int rather than Integer
The problem stems from the following potential class:
class FunnyNumber extends Integer { }
This class does not extend Comparable<T>, so it can't be used as the base T.
In other words, extends Comparable<Integer> is not the same as extends Comparable<T>.
Your second class should not be generic at all.
You should only use generics if you want to vary the type parameter.
Here, you want a single fixed type, so you should make a normal non-generic class that extends BinaryTree<Integer>. (or just use BinaryTree<Integer> directly and don't make a separate class at all)

Categories