简体   繁体   中英

Generic instance variable in abstract class

I want to make parent/abstract class which forces child classes to declare variable.

eg I have 2 abstract classes

public abstract class Key {  <something> }
public abstract class Value { <something> }

Now creating child for above.

public class ChildKey extends Key { <something> }
public class ChildValue extends Value { <something> }

I want to create a Result class which might look like

public abstract class Result {
 protected <T extends Key> key;
 protected <T extends Value> value;
}

so that I can create child of Result like

public class ChildResult extends Result {
 public ChildKey key; // this should be forcible
 public ChildValue value; // Same as above
 <some method>
}

I tried multiple things but it didn't work.

Any thoughts of how can I achieve this?

You can do it like this:

public abstract class Key {
}

public abstract class Value {
}

public class ChildKey extends Key {

}
public class ChildValue extends Value {

}

public abstract class Result<K extends Key, V extends Value> {
    protected final K key;
    protected final V value;

    protected Result(K key, V value) {
        this.key = key;
        this.value = value;
    }
}

public class ChildResult extends Result<ChildKey, ChildValue> {

    public ChildResult(ChildKey key, ChildValue value) {
        super(key, value);
    }
}

You can't use generics like that to declare variables.

public abstract class Result {
    protected Key key;
    protected Value value;


    public Result(){
        key = giveKey();
        value = giveValue();
    }

    public abstract Key giveKey();
    public abstract Value giveValue();
}

You will have to override them in ChildResult returned values will be assigned to your fields.

You can force your properties on the Result class:

public abstract class Value {}
public abstract class Key {}
public class ChildValue extends Value {}
public class ChildKey extends Key {}
// use type parameters and force attributes in your abstract class of result
public abstract class Result<K extends Key, V extends Value> {
  protected K key;
  protected V value;

  public List<String> fetchResult() {
      return new ArrayList<>();
  }
}

and use it like:

public class Main {
  public static void main(String[] args) {
      Result result = new Result<ChildKey,ChildValue>(){};
      result.fetchResult();
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM