Java Generics - Abstract Classes abstract function override - java

I am trying to implement base abstract class in android.
My base abstract class is BaseItemPresenter class. Class is below :
public abstract class BaseItemPresenter<T extends MvpView> extends BasePresenter<T> {
public abstract void loadFromDevice();
public abstract void loadFromFile();
public abstract void backup(List<? extends BaseBackupItem> list);
public abstract void delete(List<? extends BaseBackupItem> list);
public abstract void restore(List<? extends BaseBackupItem> list);
public abstract void sort(int sortType, boolean isAscending);
public abstract void sort(List<? extends BaseBackupItem> list, int sortType, boolean isAscending);
public abstract void filter(List<? extends BaseBackupItem> list, Class<? extends MvpView> filterOptions);
}
and I am implementing this class with ItemPresenter1 class. Code is below :
public class ItemPresenter1 extends BaseItemPresenter<MvpView> {
#Override
public void loadFromDevice() {
}
#Override
public void loadFromFile() {
}
#Override
public void backup(List<Item1> list) {
}
#Override
public void delete(List<Item1> list) {
}
#Override
public void restore(List<Item1> list) {
}
#Override
public void sort(int sortType, boolean isAscending) {
}
#Override
public void sort(List<Item1> list, int sortType, boolean isAscending) {
}
#Override
public void filter(List<Item1> list, Class<View1> filterOptions) {
}
}
Item1 class is extending BaseBackupItem class.
View1 class is extending MvpView class.
public class Item1 extends BaseBackupItem {
}
public class View1 extends MvpView {
}
so, how should I achieve this problem :
from :
public abstract void backup(List<? extends BaseBackupItem>);
to :
#Override
public void backup(List<Item1>);
error :
Method does not override method from its superclass.

You need to add a new type parameter to the class definition of BaseItemPresenter in order to specify the expected type of your List as next:
public abstract class BaseItemPresenter<T extends MvpView, I extends BaseBackupItem>
extends BasePresenter<T> {
...
public abstract void backup(List<I> list);
public abstract void delete(List<I> list);
public abstract void restore(List<I> list);
...
}
Then your class ItemPresenter1 will be declared as next:
public class ItemPresenter1 extends BaseItemPresenter<MvpView, Item1 > {
...
#Override
public void backup(List<Item1> list) {

Related

How to use a parameter of type `Derived` in a overridden method accepting `Base`?

I have the following situation:
abstract class Base {
int data = 0;
void baseMethod() {
System.out.println("baseMethod:" + data);
}
}
class DerivedA extends Base {
void DerivedBMethodA() {
}
void usefulMethod(Something something) {
something.doSomething(this);
}
interface Something {
void doSomething(DerivedA deriv);
}
}
class DerivedB extends Base {
void DerivedMethodB() {
}
}
public class Temp {
public static void main() {
DerivedA a = new DerivedA();
a.usefulMethod(new DerivedA.Something() {
#Override
public void doSomething(DerivedA deriv) {
deriv.DerivedBMethodA();
}
});
}
}
I want to push usefulMethod and Something upto the Base class so that DerivedB can leverage it. And I want implementations of Something.doSomething to be able to use a derived type, so that it can access derived functionality.
How do I do that?
Attempts
I've tried the following:
abstract class Base {
int data = 0;
void baseMethod() {
System.out.println("baseMethod:" + data);
}
void usefulMethod(Something something) {
something.doSomething(this);
}
interface Something {
void doSomething(Base deriv);
}
}
class DerivedA extends Base {
void DerivedBMethodA() {
}
}
class DerivedB extends Base {
void DerivedMethodB() {
}
}
public class Temp {
public static void main() {
DerivedA a = new DerivedA();
a.usefulMethod(new Base.Something() {
#Override
public void doSomething(DerivedA deriv) {
deriv.DerivedBMethodA();
}
});
}
}
but that fails as my anonymous Something doesn't implement doSomething(Base). So trying to use generics:
I tried:
interface Something {
void doSomething(<? extends Base> deriv);
}
but that won't compile due to: "Wildcards may be used only as reference parameters"
I tried:
interface Something {
<T extends Base> void doSomething(T deriv);
}
but that requires me to implement the interface as so:
a.usefulMethod(new Base.Something() {
#Override
public <T extends Base> void doSomething(T deriv) {
}
});
which obviously doesn't allow me access to the derived type?
There are ways I can make it "work" but they're undesirable:
This:
interface Something {
void doSomething(Base deriv);
}
a.usefulMethod(new Base.Something() {
#Override
public void doSomething(Base deriv) {
DerivedA a1 = (DerivedA) deriv;
a1.DerivedBMethodA();
}
});
But that requires me to cast in each implementation, which seems wasteful.
And this:
package com.miurasample.ui.info;
abstract class Base {
int data = 0;
void baseMethod() {
System.out.println("baseMethod:" + data);
}
void usefulMethod(Something something) {
something.doSomething(this);
}
interface Something<T extends Base> {
void doSomething(T deriv);
}
}
public class Temp {
public static void main() {
DerivedA a = new DerivedA();
a.usefulMethod(new Base.Something<DerivedA>() {
#Override
public void doSomething(DerivedA deriv) {
}
});
}
}
but that results in a warning/IDE highlight in usefulMethod of:
"Unchecked call to doSomething(T) as a member of raw type Base.Something"
What's the tersest and "cleanest" way to do this? Is that I'm doing even sane?
It is difficult to say if your design is wrong or not. We dont have full scope of your requirements to assert that, but here is clean non cast approach to what you are trying to do. It does require extra method in your derived classes:
public static void main(String... args) {
DerivedA a = new DerivedA();
a.usefulMethod( new Base.Something<DerivedA>() {
#Override
public void doSomething(DerivedA deriv) {
deriv.DerivedBMethodA();
}
} );
}
public abstract static class Base< T extends Base<T> > {
int data = 0;
protected abstract T getThis();
void baseMethod() {
System.out.println("baseMethod:" + data);
}
void usefulMethod(Something<T> something) {
something.doSomething( getThis() );
}
interface Something< T extends Base<T> > {
void doSomething(T deriv);
}
}
public static class DerivedA extends Base<DerivedA> {
protected DerivedA getThis(){
return this;
}
void DerivedBMethodA() {}
}
public static class DerivedB extends Base<DerivedB> {
protected DerivedB getThis(){
return this;
}
void DerivedMethodB() {}
}

getThis() trick and ClassCastException

I've been wondering about the getThis() trick, and the alternative of the unsafe cast from a self-bounded type to its type parameter.
public abstract class SelfBound<T extends SelfBound<T>> {
protected abstract T getThis();
public void doSomething(T instance) { ... }
public final void doSomethingWithThis() { doSomething(getThis()); }
public final void doSomethingWithThisUnsafe() { doSomething((T) this); }
}
Is it possible to subclass SelfBound such that doSomethingWithThisUnsafe() throws a ClassCastException? (Is it possible to do this without subclassing SelfBound?)
Surely it's possible to have ClassCastException with subclassing. Here's a simple example:
public abstract class SelfBound<T extends SelfBound<T>> {
protected abstract T getThis();
public void doSomething(T instance) { }
public final void doSomethingWithThis() { doSomething(getThis()); }
public final void doSomethingWithThisUnsafe() { doSomething((T) this); }
public static class A extends SelfBound<A> {
#Override
protected A getThis() {
return this;
}
}
public static class B extends SelfBound<A> {
#Override
public void doSomething(A instance) {
super.doSomething(instance);
}
#Override
protected A getThis() {
return null;
}
}
public static void main(String[] args) {
new B().doSomethingWithThisUnsafe();
}
}
Output:
Exception in thread "main" java.lang.ClassCastException: SelfBound$B cannot be cast to SelfBound$A
at SelfBound$B.doSomething(SelfBound.java:1)
at SelfBound.doSomethingWithThisUnsafe(SelfBound.java:6)
at SelfBound.main(SelfBound.java:28)
It's not so clear what do you mean by "without subclassing SelfBound". As SelfBound is an abstract class, you cannot call its methods without subclassing it, thus you cannot have any exception when calling its methods.

type parameter extends and method parameter mismatch error

I created something like below:
ConcreteObserver1 is the subclass of IObserver
Interfaces definitions:
public interface ISubject<T,O extends IObserver<T>> {
public void addObserver(O observer);
public void removeObserver(O observer);
public void updateAllSubjects(T value);
}
public interface IObserver<T> {
public void update(T value);
}
public class ConcreteObserver1<T> implements IObserver<T> {
Concrete Subject class containing IObserver
public class ConcreteSubject<T, O extends IObserver<T>> implements
ISubject<T,O> {
public ConcreteSubject() {
addObserver(new ConcreteObserver1<T>());
}
ConcurrentSkipListSet<O> observersList = new ConcurrentSkipListSet<O>();
public void addObserver(O observer) {
observersList.add(observer);
addObserver(new ConcreteObserver1<T>()); not working.
It complains as below
The method addObserver(O) in the type ConcreteSubject is not applicable for the arguments (ConcreteObserver1)
Why ?
I told O extends IObserver<T> in ConcreteSubject type parameter definition, which says O is a sub-type of IObserver which is ConcreteObserver1
Why it is complaining.
The type parameter O is defined to be a subtype of IObserver<T>, this is correct. But it may stand for any subtype. You don't say anywhere that it stands for ConcreteObserver1. It could also stand for ConcreteObserver42 or something else.
From what you posted so far, it does not seem like you really have to define O as a type parameter of ConcreteSubject. You could specifically say that ConcreteSubject always uses a ConcreteObserver1. If this is not the case, you should probably explain your intention more clearly (and possibly, in a more readable form).
(Edited based on the comments)
interface ISubject<T,O extends IObserver<T>>
{
void addObserver(O observer);
void removeObserver(O observer);
void updateAllSubjects(T value);
}
interface IObserver<T>
{
void update(T value);
}
class ConcreteObserver1<T> implements IObserver<T>
{
#Override
public void update(T value) {}
}
class ConcreteObserver2<T> implements IObserver<T>
{
#Override
public void update(T value) {}
}
class ConcreteObserver3<T> implements IObserver<T>
{
#Override
public void update(T value) {}
}
class ConcreteSubject<T> implements ISubject<T,IObserver<T>>
{
ConcurrentSkipListSet<IObserver<T>> observersList =
new ConcurrentSkipListSet<IObserver<T>>();
public ConcreteSubject()
{
addObserver(new ConcreteObserver1<T>());
addObserver(new ConcreteObserver2<T>());
addObserver(new ConcreteObserver3<T>());
}
#Override
public void addObserver(IObserver<T> observer)
{
observersList.add(observer);
}
#Override
public void removeObserver(IObserver<T> observer)
{
observersList.remove(observer);
}
#Override
public void updateAllSubjects(T value)
{
for (IObserver<T> observer : observersList)
{
observer.update(value);
}
}
}

Can not cast class to generics in java

Please help resolve an issue regarding generics. I tried many ways but it's still not working.
Problem is:
public static void main(String[] args) {
Utils.execute(new TestAction(), new TestCallBack());
}
Compiler show error:
The method execute(Action<?>, CallBack<?,Action<?>>) in the type Utils is not applicable for the arguments (ImplementClass.TestAction, ImplementClass.TestCallBack)
My classes is:
Action class:
public abstract class Action<R> {
public R getResult() {
return null;
}
}
TestAction class is:
class TestAction extends Action<String> {
#Override
public String getResult() {
return super.getResult();
}
}
Callback class is:
public interface CallBack<R, A extends Action<R>> {
public void onCall(A action);}
TestCallback class is:
class TestCallBack implements CallBack<String, TestAction> {
#Override
public void onCall(TestAction action) {
}
}
And Utils class is:
public class Utils {
public static void execute(Action<?> action, CallBack<?, Action<?>> callback) {
}
}
Thanks a lot.
The second parameter of the execute method is CallBack<?, Action<?>>, and Action there means the Action class itself, subclass of it is not allowed. What you need there is - ? extends Action<?>, which means either Action or some subclass of it.
Try changing the method signature -
public static void execute(Action<?> action, CallBack<?, ? extends Action<?>> callback) {
Note:
Generics are not co-variant. Take for example a method as follows -
static void method(List<Object> l) {}
And an invocation as follows is not allowed -
method(new ArrayList<String>());
You need to change two things,
TestCallBack should be like this -
public static class TestCallBack implements CallBack<String, Action<String>> {
#Override
public void onCall(Action<String> action) {
}
}
and, Utils should be like this -
public static class Utils {
// You need to ensure the same type, not just try and accept anything.
public static <T> void execute(Action<T> action, CallBack<?, Action<T>> callback) {
}
}
or using inner classes of a class called Question -
public abstract class Action<R> {
public R getResult() {
return null;
}
}
public class TestAction extends Action<String> {
#Override
public String getResult() {
return super.getResult();
}
}
public interface CallBack<R, A extends Action<R>> {
public void onCall(A action);
}
public class TestCallBack implements CallBack<String, TestAction> {
#Override
public void onCall(TestAction action) {
}
}
public class Utils {
public void execute(Action<?> action, CallBack<?, ? extends Action<?>> callback) {
}
}
public static void main(String[] args) {
Question question = new Question();
question.new Utils().execute(question.new TestAction(), question.new TestCallBack());
}

Define abstract class method argument Enum<E> for multiple values

I have a question.
How I can define an Enum type for multiple static classes with a different object as Enum?
Example:
public abstract class AbstractClass
{
public Enum<?> AbstractMethod();
}
public class StaticClass extends AbstractClass
{
public enum en
{
FOO3,
FOO4
}
#Override
public Enum<en>[] AbstractMethod()
{
return en.values();
}
}
public class StaticClass2 extends AbstractClass
{
public enum en
{
FOO1,
FOO2
}
#Override
public Enum<en>[] AbstractMethod()
{
return en.values();
}
}
But that code throws an error:
The method public boolean AbstractMethod(Enum<ObjectX> en1) dosn't exsist in AbstractClass (X is the Number of the Object)
Doing this it works but throws RawTypes warning:
public abstract class AbstractClass
{
public Enum[] AbstractMethod();
}
public class StaticClass extends AbstractClass
{
public enum en
{
FOO3,
FOO4
}
#Override
public Enum[] AbstractMethod()
{
return en.values();
}
}
public class StaticClass2 extends AbstractClass
{
public enum en
{
FOO1,
FOO2
}
#Override
public Enum[] AbstractMethod()
{
return en.values();
}
}
Is this what you mean?
Enum:
public enum Fruits {
APPLE, ORANGE;
}
Classes:
public static abstract class Parent {
public abstract <E extends Enum<?>> void printEnum(final E e);
}
public static class Child extends Parent {
#Override
public <E extends Enum<?>> void printEnum(final E e) {
System.out.println(e.name());
}
}
Usage:
new Child().printEnum(Fruits.ORANGE); // Prints ORANGE

Categories

Resources