I got a problem with java when i try to override a method,my code is following:
public abstract class CustomAdapter{
public abstract Boolean addItem(Class<? extends Object> aObject);
}
public class RainAdapter extends CustomAdapter {
#Override
public Boolean addItem(ClassOfRain aRainInfo) {
// do something
return true;
}
}
Can I declare the the "Class" to "ClassOfRain"?
If yes,how to do?
Thanks for your reading!
I think you are a bit confused. Are you sure you are not trying to say:
public abstract class CustomAdapter<T extends Object> {
public abstract Boolean addItem(T aObject);
}
public class RainAdapter extends CustomAdapter<Rain> {
#Override
public Boolean addItem(Rain aRainInfo) {
// do something
return true;
}
}
In my interpretation of your class structure, you are trying to make a generic addItem method, so passing around the actual class object is of no use.
That is not possible. A method override means that you put exactly the same method header. Only thing you can change is the name of the given parameter.
Class<Rain.class> would hold the reflection of Rain class. But this will not work, because overridden methods must have the same formal parameters, so you'll have to use Class<? extends Object>.
the method signatures must match when implementing abstract/interface methods and/or overwriting ... you could do something like this tho
public abstract class CustomAdapter{
public abstract Boolean addItem( Object o );
}
public class RainAdapter extends CustomAdapter {
public Boolean addItem( Object o ){
if ( o.getClassName().equals( "ClassOfRain" ) ){
return this.addItem( (ClassOfRain) o );
}
return false;
}
private Boolean addItem(ClassOfRain aRainInfo) {
// do something
return true;
}
}
Related
Item is an abstract class with subclasses Potion, Weapon. Shield.
The useItem() method is an abstract method defined in each of Item's subclasses
get_item return object of class Item
The getItem method returns an object of class subclass of Item
case "use":
if (hero.get_item() instanceof Potion) {
hero.<Potion>getItem(Potion.class).useItem();
} else if (hero.get_item() instanceof Weapon) {
hero.<Weapon>getItem(Weapon.class).useItem();
} else if (hero.get_item() instanceof Shield) {
hero.<Shield>getItem(Shield.class).useItem();
}
break;
is there a way I can condense this code into something like...
Class itemclass = hero.getItem().getClass();
hero.<itemclass>getItem(itemclass.class).useItem();
The code above does not compile but I am looking for something like it. I am trying to avoid if else statements because there are many more items.
Edit:
The reason i did not initially use hero.get_item().useItem() was because
i was trying to do
Weapon sword = hero.get_item();
so i could access methods such as sword.getDamage()
However, I would get the error error: incompatible types: Item cannot be converted to a Weapon
so that is why I created (help from #marsouf) hero.<Weapon>getItem(Weapon.class)
Today i created the method abstract public void useItem();
and since it is a method of the Item class I am able to use hero.getItem().useItem()
It would make more sense to haven an Interface for Item with the method useItem().
Then have an implementation for Potion, Shield etc.
This way you avoid having to cast and make it more complex than it is.
useItem() does not belong in the abstract class if its not giving any functionality, and less needed now Interfaces can have default methods.
My idea is to use the magic of generics without not cast
public class Character<T extends Item> {
private T item;
public Character (T item){
this.item = item;
}
public T getItem(){
return item;
}
}
When you create a hero:
Character hero = new Character<Weapon>(new Weapon("sword"));
after this you can use it like:
hero.getItem().useItem(); // abstract method from Item class
hero.getItem().getPower(); //where power is a Weapon method
Character class you can extend like:
public class Hero<T> extend Character<T>{
//add there your custom methods or override Character methods
}
Difficult to answer without seeing the contracts being involved (hero.get_item(), hero.getItem()).
But have you tried:
Class<?> itemClass = hero.get_item().getClass();
hero.getItem(itemClass).useIt();
?
Assuming you are set on using generics the way you're using them... here's how.
First, I've created some extremely simple classes to mimic your structure from this and your other question: a class which uses instances of a particular abstract class.
public class ACOne extends AbstractClass
{
#Override
public void use(){System.out.println("Used item ACOne!");}
}
public class ACTwo extends AbstractClass
{
#Override
public void use(){System.out.println("Used item ACTwo!");}
}
public abstract class AbstractClass
{
public abstract void use();
}
public class UserClass
{
private AbstractClass item;
public UserClass (AbstractClass item)
{
this.item = item;
}
public Class<? extends AbstractClass> getItemClass()
{
return item.getClass();
}
public <T extends AbstractClass> T getItem (Class <? extends T> targetType)
{
return targetType.cast(this.item);
}
public void setItem (AbstractClass item)
{
this.item = item;
}
}
public class CastingSubclasses
{
public void testCastingSubclasses()
{
UserClass user = new UserClass(new ACOne());
user.setItem(new ACTwo());
user.getItem(user.getItemClass()).use();
}
}
This program, when run, prints out "Used item ACTwo!"
The crux here is in the getItemClass method on the UserClass (your Character class).
Also, it's common to call these methods which get the Class object 'getClazz', since there is a default method 'getClass' that you don't want to override.
Here it made sense to just keep the spelling.
I have a problem. I have a class that extends another class and implements Comparable. But when I tried to compile my program I had this error: Flight is not abstract and does not override abstract method compareTo. Anyway, the code of Flight is this:
class Flight extends KeyFlight implements Comparable<Flight>{
public KeyFlight kf;
public boolean departure;
public void Flight(){
KeyFlight kf=new KeyFlight();
boolean departure=false;
}
public int compareTo(KeyFlight other){
if (kf.time==other.time){
if (kf.key<other.key){
return kf.key;
} else {
return other.key;
}
} else {
if (kf.time <other.time){
return kf.key;
} else {
return other.key;
}
}
}
}
Thank you in advance!
You should use
implements Comparable<KeyFlight>
Instead of
implements Comparable<Flight>
As you want to compare two keyflights rather than flights itself. The Type of parameter that you defines in compareTo, should match with the type you specified in implements clause that you are going to compare with.
Another issue with your code is, in your constructor you are re-defining KeyFlight, it should be
public void Flight(){
kf=new KeyFlight();
Else you will get NullPointerException in future. Same applies for your departure boolean.
A side note, By Default in java boolean is initialised to false, so you don't have to explicitly say that in constructor.
I think the type of compareTo's argument is wrong, it should be
public int compareTo(Flight other){
The compareTo method in your class is not to a valid override because you define that your class implement Comparable<Flight> So in order to override this method in your class you need to change the variable type of other from KeyFlight to Flight.
#Override
public int compareTo(Flight o) {
//your logic here
}
I wan't to make a method declaration in a superclass called 'dataItem' so that all subclasses that implement that method must have a return type that is of that implementing class. Is that possible?
For example if I have class 'Experiment' which implements 'dataItem' and I have method newItem() . Which for 'Experiment' should only be able to return 'Experiment' datatype and not any other implementation of 'dataItem'.
You can't force a class method to return the type it is a member of. You have to actually specify it.
public class DataItem {
public DataItem getItem() {return null;}
}
public class Experiment extends DataItem {
#Override
public Experiment getItem() {return null;}
}
This works because Experiment is a sub class of DataItem and can therefore be used anywhere a DataItem could be used.
I suppose you're looking for this:
public interface dataitem<T>
{
public T newItem();
};
public class Element implements dataitem<Element>
{
#Override
public Element newItem()
{
return new Element();
}
}
It looks like this is impossible to do, but does anyone have a clever way around this problem?
public class SomeClassIterableWrapper<S, T extends SomeClass & S> implements Iterable<S>
Where S is supposed to be an interface of some unknown type and SomeClass is a 2D array with a row index, similar in functionality to a bidirectional JDBC resultset. Subclasses of SomeClass have custom getters and setters for each column. I want to be able to iterate through this structure like I would a List. I want to implement a common interface between my SomeClass and Bean to have access to the getters and setters. As such S needs to be that interface. However the declaration I provided does not work. Is there a way to work around this?
edit to show my desired implementation:
public class SomeClassIterableWrapper<S, T extends SomeClass & S> implements Iterable<S>{
T object;
public SomeClassWrapper(T object){
this.object = object;
}
#Override
public Iterator<S> iterator() {
object.setIndex(-1);
return new SomeClassIterator<S>();
}
private class SomeClassIterator<S> implements Iterator<S> {
#Override
public boolean hasNext() {
return object.index() < object.rowSize() - 1;
}
#Override
public S next() {
object.next();
//safe because only interface methods allowed, can't further manipulate index
return object;
}
#Override
public void remove() {
object.deleteRow();
}
}
Can't you parameterize SomeClass with S? Then you could have
public class SomeClassIterableWrapper<S, T extends SomeClass<S>>
implements Iterable<S>{
I think the S in extends SomeClass & S
public class SomeClassIterableWrapper
has to be a definite class because in this context,
S has to be a class that is extending something.
Is there a way you can narrow down what the
potential classes that are used in place of S are?
You could use multiple ampersands if you have multiple
classes that T should extend
I confess that I don't fully comprehend the problem but this is what I suggest:
Create an interface of S. It contains one method ad it returns the S object.
public interface SWrapper<S> {
S getS();
}
Then create an implementation:
public class SImpl implements SWrapper<SImpl> {
#Override
public SImpl getS() {
return this;
}
}
You can now create:
public class SomeClass<T extends SomeClass & SWrapper<T>> {
private final T object;
public SomeClass(T object) {
this.object = object;
}
}
You will have to modify your usage a bit but perhaps it works.
I'm writing an abstract class in Java where I'd like a parameter of one of my abstract methods to be an enum, so I've got the following. Note that only subclasses will know what possible states it can have. (Please excuse the contrived example)
public abstract class StateTracker {
public abstract boolean isInState(???????? state);
}
What is ????????? Therein lies the problem:
Ideally it would be an abstract enum called StateEnum that has no instances, and the clients of StateTracker could make their own concrete StateEnums. But we can't do anything like that in Java.
I could make it an interface, but then I'd have no way of ensuring that the subclasses implement it as an enum, which is the goal.
I could change it to Enum < ? >. So I try that, and in my subclass I do something like this:
public class MyStateTracker extends StateTracker {
public enum MyState {
BADSTATE_1, BADSTATE_2
}
#Override
public boolean isInState(?!?!?!?! state) {
// TODO Auto-generated method stub
return false;
}
}
Now what is ?!?!?!?! Here are the possibilities:
MyState. This doesn't compile since it doesn't think that I'm overriding the abstract method.
Enum. Same problem.
How can I ensure that concrete classes use an emum?
It depends on whether you want to be able to ask a StateTracker whether it is in states declared by different enum types.
If you want to lock down the states so that a given state tracker can only be queried for one type of enum, create a generic type:
interface StateTracker<S extends Enum<S>> {
boolean isInState(S state);
}
final class MyStateTracker implements StateTracker<MyStateTracker.MyState> {
enum MyState { S1, S2 };
private MyState state;
...
#Override
public boolean isInState(MyState state) {
return state == this.state;
}
}
If you have a couple of enum types defining states like this:
enum MyState { S1, S2 }
enum YourState { S1, S2 };
… and you want to be able to ask a StateTracker whether it is in any state (defined by any enum, really, unless you also declare a State marker interface for your enum to implement), then create a generic method:
interface StateTracker {
<S extends Enum<S>> boolean isInState(S state);
}
class StateTracker<E extends Enum<E>> {
public abstract boolean isInState(E state);
}
You can use generics to achieve this, Java's enums all extend implicitly java.lang.Enum:
abstract class StateTracker<T extends Enum<?>> {
public abstract boolean isInState(T state);
}
enum MyState {
State_1, State_2
}
class State extends StateTracker<MyState>
{
private MyState currentState = MyState.State_2;
#Override
public boolean isInState(MyState state)
{
return state.equals(currentState);
}
}
public class TestEnum
{
#Test
public void testIsInState()
{
State state = new State();
Assert.assertFalse(state.isInState(MyState.State_1));
Assert.assertTrue(state.isInState(MyState.State_2));
}
}
//This won't compile, so the generic-type must be an Enum
/*
class State2 extends StateTracker<String> //<-- Bound mismatch: The type String is not a valid substitute for the bounded parameter <T extends Enum<?>> of the type StateTracker<T>
{
#Override
public boolean isInState(String state)
{
// TODO Auto-generated method stub
return false;
}
}
*/