Not able to override method with generics - java

I have following methods defined in interface
public interface Stack<T> {
void method1(T element);
T method2();
}
Class Implementing this interface implements these methods as follows
private List<T> elements;
#Override
public void method1(T element) {
elements.add(element);
}
#Override
public T method2() {
return elements.remove(elements.size() - 1);
}
With this I get following error for method1: Method does not override method from super class, while method2 works fine.
Any idea what am I doing wrong?

This works perfectly fine:
import java.util.ArrayList;
import java.util.List;
public class Main {
interface MyStack<T> {
void push(T item);
T pop();
}
static class MyStackImpl<T> implements MyStack<T> {
private List<T> items = new ArrayList<T>();
#Override
public void push(T item) {
items.add(item);
}
#Override
public T pop() {
return items.remove(items.size() - 1);
}
}
public static void main(String[] args) {
MyStack<Integer> stack = new MyStackImpl<Integer>();
stack.push(42);
System.out.println(stack.pop());
}
}

You need to add type parameter to the interface and to the class too:
public interface Stack<T> { // here it is: <T>
void method1(T element);
T method2();
}
public class Impl<T> implements Stack<T> { // and here too
private List<T> elements;
#Override
public void method1(T element) {
elements.add(element);
}
#Override
public T method2() {
return elements.remove(elements.size() - 1);
}
}

You just need to specify the interface's generic type interface Stack<T>.
public interface Stack<T> {
void method1(T element);
T method2();
}
And you also need to define the generic type in you implementation class YourStack<T>
class YourStack<T> implements Stack<T>{
private List<T> elements;
#Override
public void method1(T element) {
elements.add(element);
}
#Override
public T method2() {
return elements.remove(elements.size() - 1);
}
}

Related

How to implement an interface for two classes with an iterator

I'm trying out Interfaces in java and I want to implement a common interface for a really simple stack, with pop() and push() methods and an iterator.
The problem is that I don't know how to specify the iterator in the interface. No matter which way I try, I get
Main.java:32: error: for-each not applicable to expression type
for (Integer i : ss)
^
required: array or java.lang.Iterable
found: Stack<Integer>
The code is as follows:
interface Stack<T> {
boolean push(T t);
boolean pop();
//Iterator<T> iterator(); // How to indicate it needs, and will have, an iterator?
}
public class DynamicStack<T> implements Iterable<T>, Stack<T>
{
// implementation-specific variables go here
public DynamicStack() {
//...
}
public boolean push(T t) {
//...
}
public boolean pop() {
//...
}
private class StackIterator implements Iterator<T> {
DynamicStack<T> stk;
//...
// Iterator constructor
private StackIterator(DynamicStack<T> stk)
{
//...
}
public boolean hasNext()
{
//...
}
public T next() throws NoSuchElementException
{
//...
}
public void remove() throws UnsupportedOperationException
{
throw new UnsupportedOperationException(); // I chose not to implement this one
}
}
// Iterator method
public Iterator<T> iterator()
{
return new StackIterator(this);
}
}
public class StaticStack<T> implements Iterable<T>, Stack<T>
{
// implementation-specific variables go here
public StaticStack()
{
//...
}
public boolean push(T t)
{
//...
}
public boolean pop()
{
//...
}
private class StackIterator implements Iterator<T>
{
StaticStack<T> stk;
//...
private StackIterator(StaticStack<T> stk)
{
//...
}
public boolean hasNext()
{
//...
}
public T next() throws NoSuchElementException
{
//...
}
public void remove() throws UnsupportedOperationException
{
//...
}
}
// Iterator method
public Iterator<T> iterator()
{
return new StackIterator(this);
}
}
Main simply does this, after creating a few stacks of each type and adding a few elements:
public static void showStuff(Stack<Integer> ss)
{
for (Integer i : ss)
System.out.print(i+" ");
System.out.println();
}
In your test class, you are operating against Stack interface, so that is the one that needs to conform to Iterable. In this case it doesn't help if StaticStack or DynamicStack implement it if Stack does not.
To get Stack to be able to be used as Iterable just change your Stack to extend Iterable:
public interface Stack<T> extends Iterable<T> {
boolean push(T t);
boolean pop();
}
and
public class StaticStack<T> implements Stack<T>
and the code runs just fine:
public class Tester {
public static void main(String args[]) {
Stack<Integer> ss = new StaticStack<>();
for (Integer i : ss)
System.out.print(i+" ");
System.out.println();
}
}
You need you class to implement Iterable<T>, which has the iterator() method, which returns Iterator<T>.

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() {}
}

How to create a collection of different types objects to use it with polymorphis

I have a problem with the different type of objects in a collection, in that case ArrayList, here there is an example:
public interface CustomObject {}
public class CustomObjectA implements CustomObjects {}
public class CustomObjectB implements CustomObjects {}
In the main I call myMethod:
ArrayList<CustomObject> list = new ArrayList<>();
for(int i=0; i < list.size(); i++) {
myMethod(list.get(i));
}
myMethod is defined with an overloading as written below:
public void myMethod(CustomObjectA a) { ... }
public void myMethod(CustomObjectB b) { ... }
There is a compile-error. How can I solve? What's the right way to it (Collections, generics, wildcard ?)
One way to work around this is the use of the visitor pattern, which allows you to attach functionality, without touching your domain objects
// A visitor, which can 'visit' all your types
interface CustomObjectVisitor {
void visitA(CustomObjectA a);
void visitB(CustomObjectB b);
}
// Make CustomObject a visitee
public interface CustomObject {
void accept(CustomObjectVisitor visitor);
}
// Implement the classes with the accept method
public class CustomObjectA implements CustomObject {
#Override public void accept(CustomObjectVisitor visitor) {
visitor.visitA(this);
}
}
public class CustomObjectB implements CustomObject {
#Override public void accept(CustomObjectVisitor visitor) {
visitor.visitB(this);
}
}
Now you can make your Main class a visitor like this:
public class Main implements CustomObjectVisitor {
public void methodThatDidntWorkBefore() {
ArrayList<CustomObject> list = new ArrayList<>();
for(CustomObject obj: list) {
obj.accept(this);
}
}
#Override public void visitA(CustomObjectA a) { ... }
#Override public void visitB(CustomObjectB b) { ... }
}
Check out WikiPedia too, it's really useful once you wrap your head around it.
With:
public interface CustomObject { void myMethod(); }
public class CustomObjectA implements CustomObjects {
#Override
public void myMethod() {...}
}
public class CustomObjectB implements CustomObjects {
#Override
public void myMethod() {...}
}
Then:
ArrayList<CustomObject> list = new ArrayList<>();
for(int i=0; i < list.size(); i++) {
list.get(i).myMethod(); // invoke dynamic
}
Which will execute the method corresponding to what the object's dynamic type is.
e.g. If get(i) returns an object with a dynamic type of CustomObjectA it will execute CustomObjectA::myMethod.
You could try something like this:
public class myMethodClass {
public static void main(String[] args) {
ArrayList<CustomObject> list = new ArrayList<>();
for(int i=0; i < list.size(); i++) {
myMethod(list.get(i));
}
}
public static void myMethod(CustomObject o){
if(o instanceof CustomObjectA) myMethod((CustomObjectA) o);
if(o instanceof CustomObjectB) myMethod((CustomObjectB) o);
}
public static void myMethod(CustomObjectA a) { }
public static void myMethod(CustomObjectB b) { }
}
interface CustomObject {}
class CustomObjectA implements CustomObject {}
class CustomObjectB implements CustomObject {}

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());
}

defining a method using inherited methods

I'm trying to define void add(T thing) method by using the inherited push method of a stack but Eclipse says the return type is incompatible with Vector<T>.add(T) and wants me to change the return type of add(T) to boolean which doesn't make sense.
Below is my code
public class ListStack<T> extends Stack<T> implements SomeList<T>{
Stack<T> stack1=new Stack<T>();
public ListStack(){//constructor
super();
stack1=new Stack<T>();
}
//add method
public void add(T something){
this.push(something);}
}
Here's my SomeList interface
public interface SomeList<T>{
public void add(T something);
public void take(T idx);
.
.
.
}
Well since you're holding an instance of Stack<T> as member you don't need to inherit from the very same class.
Remove the inheritance and use your member instead:
public void add(T something){
stack1.push(something);
}
If you no longer subclass Stack<T> your compiler shouldn't complain about the different return types of add(T) anymore.
I think you should have a look into the adapter pattern.
Here's how I would do it:
Interface
interface MyList<T> {
public void addFront(T thing);
public void remove(int pos);
public void removeEnd();
public T get(int pos);
public int length();
public boolean isEmpty();
}
Implementation
class MyListImpl<T> implements MyList {
Stack<T> mStack;
public MyListImpl() {
mStack = new Stack<T>();
}
public void addFront(T thing) {
mStack.push(thing);
}
public void remove(int pos) {
//mStack...
}
public void removeEnd() {
//mStack...
}
public T get(int pos) {
// return mStack...
}
public int length() {
// return mStack...
}
public boolean isEmpty() {
// return mStack...
}
}
Your Stack Class must be having the method add() with a return type of boolean
Stack class extends Vector class, which contains boolean add(E e). I think Eclipse confuses between the add method in Vector, and the add method in your SomeList interface.

Categories

Resources