2017-01-21 3 views
1

Прошу прощения, если эти пустые значения/переменные не являются общими элементами, я действительно не уверен в терминологии в Java.Наследование в Java с помощью общих элементов

Мы получили этот код:

public class AbstrClass <T, S> { 
    private T value1; 
    protected S value2; 

    protected AbstrClass (T value1, S value2) { 
    this.value1 = value1; 
    this.value2 = value2; 
} 

    public T getValue1() { 
    return value1; 
} 

    public S getValue2() { 
    return value2; 
} 

} 

public class Impl extends AbstrClass<String, Double> { 

    protected Integer value2; 

    public Impl (String value1, int value2) { 
    super("Ferdinand", (double) value2); 
    this.value2 = value2 + value2; 
} 

    public void incrementValue2 (Integer value) { 
    super.value2 += value; 
} 

public static void main(String[] args) { 

    Impl impl = new Impl("Horst", 21); 
    System.out.println(impl.getValue1()); 
    System.out.println(impl.getValue2()); 
    impl.incrementValue2(42); 
    System.out.println(impl.value2); 
    System.out.println(impl.getValue2()); 
} 
} 

И тогда мы спросили, что результат был, если мы запустим код/​​main метод и почему.
Я не уверен, если мои рассуждения правильно:

  1. Ferdinand -> б/с он выполняет метод, наследуемый от основания AbstrClass, и так как это уже значение, он выводит, что один.
  2. 21.0 -> b/c он выдает метод, который он наследует от AbstrClass, но в нем нет значения, поэтому он выдает заданное значение 21, но как double, так как он определен в Impl как двойной стоимость.
  3. 42 -> этого я действительно не понимаю.
  4. 63,0 -> снова это exectues от AbstrClass (см вопрос 2), и мы добавим 42 из метода приращений, что приводит к 63.

ли мои рассуждения правильны, и почему третий System.out.println привести к 42?

ответ

1

В конструктор Impl написано:

this.value2 = value2 + value2; 

Значение для данного входа 21, value2 будет иметь значение 42.
impl.incrementValue2(42); влияет только на переменную с тем же именем в классе super.

System.out.println(impl.value2); напечатает значение переменной value2 из Impl - который был установлен в 42 в конструкторе.

Ваше общее рассуждение хорошо, а не 100% от точки

  1. он вызывает getValue1 на базовый класс, который печатает value1. value1 был установлен в конструкторе родительского класса на все, что было передано в качестве первого аргумента. Конструктор игнорирует свой первый параметр и всегда проходит "Ferdinand", поэтому суперструктор
  2. он вызывает getValue2 в базовом классе, который печатает value2 базового класса. Тот факт, что Impl имеет переменную с тем же именем, не имеет значения. Ваши аргументы в пользу .0 верны.
  3. см базовая часть ответа
  4. Возможно указать немного более точно, почему значение value2 в супер классе changed`
2

Это путаница вызвана чем-то называется полем Hidding. Когда у вас одинаковое имя поля в нескольких классах в одной иерархии наследования, у вас есть несколько разных полей.

Итак, есть Impl.value2 и AbstrClass.value, есть разница, если вы вызываете this.value2 или super.value2 в Impl.

System.out.println(((AbstrClass<String,Double>) impl).value2); 

напечатает 63.0

1

Ваши рассуждения верны. Для третьего выхода вызов impl.value2 получит value2, объявленный в реализации, а не один из родительского класса. Это связано с тем, что в отличие от методов доступ к полям членов не разрешен полиморфно, вместо этого он равен во время компиляции. Другими словами, выражение доступа к полю o.x будет обращаться к полю x, которое относится к типу, используемому для объявления o, независимо от фактического типа o во время выполнения.

value2 в подклассе указан скрыть тот, что находится в родительском классе, так как он имеет то же имя.

1

Это сводится к следующему:

  • методы могут быть перекрыты
  • поля не могут быть переопределены

т.е. super.foo всегда будет ссылаться на поле foo в суперкласса, даже если вы имеют одно и то же имя в подклассе.