достижение полиморфизма в родительском классе с помощью instanceof для установки атрибута

У меня есть родительский класс AggDef, который является базовым типом некоторых дочерних классов (TermAggDef, StatAggDeff и т. д.). Класс определен ниже.

У меня есть код в другом классе, который перебирает список объектов AggDef и получает их типы. защищенные агрегации карт = new HashMap();

public List<String> getAggregationTypes(){
    HashSet<String> aggTypes = new HashSet<String>();
      Iterator it = aggregations.entrySet().iterator();
      while (it.hasNext()) {
         Map.Entry pair = (Map.Entry)it.next();
         AggDef aggDef = (AggDef) pair.getValue();
         aggTypes.add(aggDef.getType());
      }
      List<String> retList = new ArrayList<String>();
      retList.addAll(aggTypes);
    return retList;
}

Мой вопрос: могу ли я добиться этого полиморфного присвоения атрибута типа в самом родительском классе? Потому что везде, где будет использоваться объект AggDef, он будет знать, к какому типу он относится. Член моей команды сказал, что мне следует реализовать метод setType в реальных дочерних классах. Но я не думаю, что то, что у меня есть, неправильно. Любая помощь или уточнение точности моего подхода были бы очень полезны. Заранее спасибо.

public abstract class AggDef implements Cloneable {
    protected String name;
    protected String term;
    protected String type;
    ...

    protected List<AggDef> subAggregations;

    public void setType(AggDef def){
        if(def instanceof TermAggDef){
            def.type = "terms";
        } 
        else if (def instanceof StatAggDef){
            def.type = "terms_stats";
        }
        else if (def instanceof RangeAggDef){
            def.type = "range";
        }
    }

    public String getType(){
        return type;
    }

    protected AggDef() {
        setType(this);
    }

    protected AggDef(String term) {
        this.term = term;
        setType(this);
    }

    protected AggDef(String name, String term) {
        this.name = name;
        this.term = term;
        setType(this);
    }


    public AggDef(String term, String order, int size, int offset, boolean isAllTerms) {
        this.term = term;
        this.size = size;
        ...

        setType(this);
    }


    public AggDef(String name, String term, String order, int size, int offset, boolean isAllTerms) {
        this.name = name;
        this.term = term;
       ...
        setType(this);
    }
 }

person Horse Voice    schedule 14.08.2015    source источник
comment
зачем вам метод setType и почему он получает класс в качестве аргумента (а не просто работает с этим)? в любом случае, лучший способ сделать это - сделать его абстрактным методом, и каждый реализующий класс должен определить свой собственный тип   -  person Nir Levy    schedule 14.08.2015
comment
Спасибо. Но мой вопрос был, это точно так, как у меня есть? Или это не сработает?   -  person Horse Voice    schedule 14.08.2015
comment
это будет работать? да. Это точно? нисколько. вся идея абстрактных классов заключается в том, что вы позволяете подклассам иметь свою собственную конкретную реализацию метода. то, что вы сделали в своей функции setType, имеет конкретную реализацию для каждого подкласса, но вместо того, чтобы иметь ее в подклассе, у вас есть все это в верхнем. так что это будет работать, но это плохое объектно-ориентированное программирование   -  person Nir Levy    schedule 15.08.2015
comment
Не согласно одному из ответов ниже. Мне нужен конкретный ответ. Некоторые люди говорят, что да, это сработает. Другие говорят, что этого не будет. Есть причины?   -  person Horse Voice    schedule 15.08.2015


Ответы (1)


AggDef знает только о себе и ничего не может знать о своих потомках. Поэтому, когда он вызывает setType(AggDef), JVM будет ссылаться на локально определенный метод, а не на переопределенный.

Надеюсь, чтобы помочь в дальнейшем разобраться в теме, скажем, у вас есть:

AggDef aDefObj = new AggDef();
TermAggDef taDefObj = new TermAggDef();

то это означает следующее:

aDefObj instanceOf AggDef // true 
aDefObj instanceOf TermAggDef  // false 
taDefObj instanceOf AggDef // true
taDefObj instanceOf TermAggDef // true

Ознакомьтесь с документом Oracle Наследование, посвященным приведению типов.

person zec    schedule 14.08.2015
comment
Согласно @Nir в комментариях, это должно работать нормально. - person Horse Voice; 15.08.2015