Наследование полей в Java?
Что происходит, когда суперкласс имеет поле с пометкой final, но подкласс переопределяет (скрывает? это поле? "Финал" не остановит это, не так ли? Конкретный пример, над которым я работаю, - это класс Building, от которого наследуются различные типы зданий. Стоимость каждого типа, среди прочего, должна быть окончательной для каждого подкласса, но каждый тип здания должен иметь свою собственную стоимость.
Edit: с тех пор я понял, что понятия не имел, о чем я говорил выше. Что я на самом деле нужны статические переменные затраты. Однако, если я объявляю эти статические переменные в суперклассе, они статичны для суперкласса, поэтому Подкласс1.стоимость, например, относится к тому же значению, что и суперкласс.стоимость или Подкласс2.стоимость. Как я могу сделать переменные статическими для каждого подкласса, не объявляя их в каждом классе.
3 ответов
The final
ключевое слово, применяемое к полям класса Java, не имеет ничего общего с наследованием. Вместо этого он указывает, что вне конструктора это поле не может быть переназначено.
Java обрабатывает скрытие и переопределение имени отдельно. Переопределение фактически изменяет наблюдаемое поведение программы во время выполнения, переключая, какая функция вызывается, в то время как скрытие имени изменяет программу, изменяя статическую интерпретацию, на которую ссылается поле. final
применительно к переопределению работает только для методов, потому что поля в Java не могут быть переопределены. Использование final
в этих различных контекстах немного запутанно, к сожалению, и нет никакого способа предотвратить поле от его имени, скрытого в подклассе.
если вы хотите, чтобы здания имели разные затраты, одним из вариантов было бы переопределить getCost
метод, который переопределяется по-разному в каждом производном классе. Кроме того, у вас может быть один protected
или private
поле в базовом классе, который хранит стоимость, затем каждый подкласс устанавливает это поле либо напрямую (если это protected
) или через конструктор базового класса (если это поле private
).
надеюсь, что это помогает!
вы можете сделать это двумя способами: сделать функцию доступа и скрыть само поле или передать стоимость здания конструктору суперкласса из подкласса. Вы можете объединить их и сделать свойство, которое не может быть переопределено подклассами:
public class Building {
private final int cost;
protected Building(int cost, ...) {
this.cost = cost;
}
public final int getCost() {
return cost;
}
}
public class Cottage extends Building {
public Cottage() {
super(COTTAGE_COST, ...);
}
}
согласен с другими ответами, но я думаю, что следующая реализация лучше в этом случае:
public abstract class Building {
private final int cost;
public Building(int cost) {
this.cost = cost;
}
public final int getCost() {
return cost;
}
}
class Skyscraper extends Building {
public Skyscraper() {
super(100500);
}
}
конечно, поле может быть обнародовано, но это другая история...