Наследование Java ... Запутано - PullRequest
1 голос
/ 25 апреля 2011

У меня есть абстрактный родительский класс с несколькими дочерними элементами.Я бы хотел, чтобы у ребенка была переменная, одинаковая для каждого экземпляра этого ребенка.Я бы предпочел не передавать конструктор ребенку, называя его именем, потому что это просто глупо, когда его можно жестко закодировать.Из того, что я прочитал, следующее «скрывает» родительскую переменную экземпляра и не работает так, как я хочу.

public abstract class Parent {
    public String name = "the parent";
    public getName(name);
}
public class Child1 extends Parent {
    public String name = "Jon";
}
public class Child2 extends Parent {
    public String name = "Mary";
}

Child1 c = new Child1();
c.getName(); // want this to return "Jon", but instead returns "the parent".

Чтобы быть понятным, в основном то, что я хочу, это что-то вроде c.getClass ().getName (), но я не хочу, чтобы результат этого зависел от имени класса, а скорее от жестко заданного значения.

Спасибо

Ответы [ 8 ]

6 голосов
/ 25 апреля 2011

Вы можете объявить абстрактный метод в родительском и заставить каждого потомка реализовать метод для возврата соответствующего имени, например:

public abstract class Parent {
    public abstract String getName();
}

public class Child1 extends Parent {
    private static final String NAME = "Jon";
    public String getName() { return NAME; }
}

public class Child2 extends Parent {
    private static final String NAME = "Mary";
    public String getName() { return NAME; }
}
3 голосов
/ 25 апреля 2011

В зависимости от того, что вы на самом деле пытаетесь, есть несколько решений.Один из них - заставить дочерние классы предоставить имя родителю:

public abstract class Parent {
    protected Parent(String name) {
        this.name = name;
    }
    public getName() {return name;}
}
public class Child1 extends Parent {
    public Child1() {
        super("Jon");
    }

}
public class Child2 extends Parent {
    public Child2() {
        super("Mary");
    }
}

Другой - использовать наследование методов , как предлагает Исаак Труетт .

3 голосов
/ 25 апреля 2011

Используйте метод вместо поля (переменной):

public abstract class Parent {
  public String getName() {
    return "the parent";
  }
}

public class Child1 extends Parent {
  public String getName() {
    return "Jon";
  }
}
public class Child2 extends Parent {
  public String getName() {
    return "Mary";
  }
}

В Java, по крайней мере, вы можете переопределять только методы, а не переменные.

Другим вариантом было бы, чтобы конструктор Parent принял имя в качестве параметра. Если вы сделаете это, лучше всего, если Parent является абстрактным и все конструкторы принимают параметр name. Затем подклассы должны передать имя, что обычно делается примерно так:

public class Child1 extends Parent {
  public Child1() {
    this("Jon");
    // ...
  }
}

На самом деле, даже с подходом переопределения методов, было бы хорошо, если Parent является абстрактным, поэтому вы можете сделать getName() абстрактным.

3 голосов
/ 25 апреля 2011

Создайте static final String у каждого ребенка с вашим жестко заданным именем:

public class Child1 extends Parent 
{
    public static final String NAME = "Jon";
}
1 голос
/ 25 апреля 2011

Причина, по которой ваш вызов getName() не возвращает имя дочернего элемента, заключается в том, что вы создали новое переменное имя вызова в дочернем элементе.Попробуйте это:

public class Child3 extends Parent{
    public String name = "Jon";

    public String getNames(){
        return super.name + " : " + name;
    }
}

Вы увидите:

the parent : Jon

Правильный способ указать имя ребенка в переменной name родителя состоит в следующем:

super.name = "Jon";
0 голосов
/ 25 апреля 2011

Вы могли бы сделать это, используя Java Reflection ... но это не очень чистый способ сделать вещи:

public abstract class Parent {
    public String name = "the parent";
    public String getName() throws Exception { return getClass().getField("name").get(this).toString(); }
}

Хотя я думаю, что подход Исаака - лучший способ приблизиться к решению.

0 голосов
/ 25 апреля 2011

Почему бы не использовать конструкторы?

public abstract class Parent {
    public String name = "the parent";
    public String getName() {
      return name;
    }
    public void setName(String s){
      name = s;
    }
}
public class Child1 extends Parent {
    public Child1() {
      setName("Jon");
    }
}
public class Child2 extends Parent {
    public Child2() {
      setName("Mary");
    }
}

Child1 c = new Child1();
c.getName(); 

// Печатает 'Jon'

0 голосов
/ 25 апреля 2011

Вам нужно переписать функцию getName, чтобы получить желаемый результат.Поскольку новое имя String не заменяет родительское имя, функция getName фактически читает родительскую строку String

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...