2013-07-24 2 views
1

Я родом из C++, и на самом деле я еще не использовал наследование класса в колледже, поэтому я учусь сам. Я стану сомневаться в форме примера:Проблема видимости в Java

Предположим, у меня есть класс под названием Entity. Этот класс сущностей содержит два целых числа, представляющие некоторые координаты X и Y (это не имеет значения, это может быть любое другое поле). Затем у меня есть мой класс Player, расширяющий Entity. Как бы это ни казалось обычным, я хочу, чтобы Player также использовал поля x и y, а некоторый код в классе Entity также относится к этим полям.

Теперь я сомневаюсь. Являются ли x и y общедоступными, частными или защищенными? Я чувствую, что они должны быть защищены, поскольку публика не является вариантом (другие классы не должны обращаться к ней), а private не позволяет мне использовать поля x и y из расширенного (Player) класса. Но я читал в других местах, что поля классов никогда не должны быть защищены, а только методы.

Другие решения для этого, кроме установки переменной в защищенную, которая приходит в голову, будут использовать геттеры и сеттеры из суперкласса (что, на мой взгляд, является не только плохой практикой, но и полностью избыточным и ненужным) объявляя эти атрибуты в новом классе, что позволяет мне думать, получаю ли я вознаграждение от наследования, если мне придется вводить все объявления полей дважды. Я даже не знаю, может ли эта последняя работа работать, поскольку я не знаю Java, чтобы хорошо знать, как она справляется с этими проблемами видимости.

Любая помощь по этой теме будет высоко оценена.

спасибо.

+0

http://stackoverflow.com/questions/1568091/why-use-getters-and-setters – Ted

ответ

1

Это действительно зависит от Цель от класса Entity.Если его справедливый обладатель x и y - потому что многие из ваших классов будут использовать их, то это прекрасно, чтобы защитить их.

Если есть какая-либо логика, связанная с этими координатами - особенно проверка, некоторое событие после изменения. Затем вам нужно использовать геттеры/сеттеры для инкапсуляции этой логики в класс Entity.

Ничего не установлено в камне, и вы можете все это переработать - пока другие разработчики не зависят от этого. Если у вас есть другие, зависящие от вашего кода, вам нужно более безопасно проектировать. Но не переоценивайте.

+0

Думаю, теперь я это вижу. Основная проблема заключается в том, что я использую наследование, когда это действительно не нужно, или я не получаю от этого большой пользы. Но, в любом случае, вы правы, геттеры и сеттеры - это путь, чтобы попытаться инкапсулировать функциональные возможности, которые не нужно видеть, и если я хорошо организую свои пакеты, защита не так уж плоха, когда у них есть простые целочисленные поля, которые являются просто владельцами. спасибо – Setzer22

2

Если вы хотите, чтобы переменные были доступны через subclass, вам необходимо сделать их protected. но все же они будут доступны из других classes, но в том же package. однако они будут защищены от классов за пределами пакета, кроме тех, кто наследует ваш класс, где определены переменные.

И да, вместо того, чтобы делать переменные самими частными, вы должны определить setters для доступа к ним. Это совсем не плохая практика, на самом деле ее лучшая практика во всех объектно-ориентированных программах.

4

[Использование методов получения и установки] ... на мой взгляд, это не только плохая практика, но совершенно излишним и ненужным

На самом деле нет, это часто считается лучшим подходом. Есть a variety of reasons в поддержку, начиная от ремонтопригодности до обеспечения безопасности. Вы должны сделать поля private и объявить методы в базовом классе как для доступа, так и для их изменения.

+0

Ну, у вас есть точка зрения, я не чувствую, что это избыточно, но, безусловно, нужно иметь доступ метод доступа к свойствам медленнее, если только некоторые оптимизации низкого уровня, о которых я не знаю, сделаны компилятором интерпретатора/JIT ... – Setzer22

+0

Я думаю, что основная причина, по которой получатели и сеттеры - такая хорошая практика, заключается в том, что утверждение '[class] .getX() = y' не будет работать. конечно, вы можете использовать метод 'setX()', но только если вы создадите этот метод. Но таким образом вы можете контролировать возможность внесения изменений в поля, что важно, если у вас есть что-то вроде публичного api, что вы не хотите, чтобы люди взламывали – scottyseus

+0

@ Setzer22 Разница во времени между вызовом метода, который напрямую возвращает поле и получает доступ само поле ничтожно. Вы не должны беспокоиться о такой минимальной оптимизации. – arshajii

0

Не могли бы вы использовать спецификатор доступа в этом случае? Использование protected (если я ошибаюсь) позволяет получить доступ к всем подклассам, в том числе из разных пакетов. В большинстве (но не во всех) случаях, когда вы просто создаете небольшую программу для себя, если вы хотите, чтобы подкласс имел доступ к переменной суперкласса, вы могли просто не иметь спецификатора доступа.

Эта фотография должна предоставить вам информацию обо всех различных спецификаторах доступа. Столбец «Пакет» относится к подклассам в одном пакете, а столбец «Подкласс» относится к подклассам независимо от пакета. enter image description here

+0

Я думал, что не использовать спецификатор доступа в поле, сделав его закрытым по умолчанию, как на C# или C++, я также учту это. – Setzer22

Смежные вопросы