Вопрос по java, field, abstract-class – Как обойти отсутствие абстрактных полей в Java?

5

Предположим, у нас есть абстрактный классA и мы хотим заставить все подклассы иметь определенное поле. Это невозможно в Java, потому что мы не можем определять абстрактные поля.

Workaround 1: Вынудить подклассы реализовать метод, который доставляет требуемое значение.

abstract class A {
  abstract int getA();
}

DrawbackКаждый подкласс должен реализовывать метод для каждого абстрактного поля, которое мы хотим иметь. Это может привести ко многим реализациям методов.

Advantage: Мы можем использовать методgetA в абстрактном классе и реализовать методы с ним вA без реализации их в каждом подклассе. Но значение метода не может быть перезаписано абстрактным классом.

Workaround 2: Смоделируйте абстрактное поле, заставив подкласс присвоить абстрактному классу значение.

abstract class A {
  int a;

  public A(int a) {
    this.a = a;
  }
}

Drawback: Когда у нас есть несколько полей (& gt; 10), вызов супер-конструктора будет выглядеть немного уродливо и запутанно.

Advantage: Мы можем использовать полеa в абстрактном классе и реализовать методы с ним вA без реализации их в каждом подклассе. Плюс ценностьa может быть перезаписано абстрактным классом.

Question: Какой обходной путь является наиболее распространенным способом достижения цели? Может быть, есть лучше, чем выше?

Или вы можете предоставить реализацию по умолчаниюgetA() и просто переопределите его там, где вы хотите другое значение. Keppil
Я что-то пропустил? Почему бы просто не дать абстрактному классу защищенныйconcrete поле? Почему желание & quot;abstract& Quot; поле? С чего начать абстрактное поле? Опять же, что я упускаю или не понимаю? Я слишком упрощаю твою проблему? И какую проблему с поведением (а не проблему кода) вы пытаетесь решить? Hovercraft Full Of Eels
Why Вы хотите, чтобы у всех подклассов было поле? Проблема, как правило, лучше формулируется с точки зрения принуждения ихbehavior, который вы просто делаете со спецификациями метода. Louis Wasserman

Ваш Ответ

5   ответов
2

Абстрактный метод, вероятно, является наиболее объектно-ориентированным.

Если у вас слишком много полей, вы можете перегруппировать их в POJO (если подходит новая концепция).

Сделайте его универсальным методом, и он может не только не существовать, но и его тип может еще не существовать.
Приятной особенностью является то, что a может даже не существовать: int getA () {return 4;} если свойство a всегда 4 для подкласса или getA () {return b + c;}, если оно зависит от других полей.
0

Я думаю, что opt.1 намного чище. Несколько методов получения и установки не имеют большого значения, и я сомневаюсь, что во многих случаях использования было бы больше, чем просто несколько абстрактных «полей».

Что касается opt.2, вы забываете, что конструкторы не наследуются, и, следовательно, потребуется, чтобы все конструкторы подклассов были реализованы таким образом, чтобыa в учетную запись.

0

Обходной путь 2 очень распространен из-за двух преимуществ:

1) упомянутое вами - поле не принадлежит подклассу - оно принадлежит родительскому элементу, и это важно, поскольку оно было «востребовано» родителем и потому, что родитель может использовать его

2) При подклассе от родителя вы очень хорошо знаете это поле, потому что когда вы реализуете конструктор, вы должны передать его. Если бы я увидел первый обходной путь, я бы не знал, что из него понять, таким образом, я понимаю, что родительскому классу нужно, чтобы это поле работало, поэтому оно должно иметь значимое значение.

примечание: если у вас есть класс с 10 полями, которые нужно инициализировать, возможно, что-то не так в вашем дизайне.

0

1. На самом деле это не о том, что кто-то предпочитает, а оflexibility, and the ability to adapt changes.

2. Всегда лучшеEncapsulate Behaviors that keeps changing, either into an Interface or Abstract class.

3. Вы1st Workaround будет хорошо в тех местах, где выneed different implementation for the same Behavior in Different classes, Тогда на этом месте либоInterface или ваш1st Workaround будет хорошим выбором.

Eg:

РассматриватьPainting как класс сpaint() Метод.

Сейчас

paint() Метод может иметь стили поглаживания, скольжения, затенения и т. д.

Then its better to Encapsulate that method into an Abstract class or an Interface.

public interface Paint{

paintDoIt(String style);

}

4. Ваш2nd Wordaround будет хорошо в месте,where you want certain behaviors to be MUST implemented by the Subclass.

Например:

РассматриватьCar as an Abstract Class, Сейчасto be car очень важно, чтобыit must have a Steering, 4 wheels, Engine, etc. So these features must be implemented.

в то время какother features like music system, LCD ,etc are optional и зависит от типа автомобиля.

1

Я предпочитаю первый. я не люблю соединять классы в именах файлов, как они обрабатывают состояние и как они его сохраняют. первый ближе коткрыть / закрыть принципал

Я рекомендую избегать наследования. Наследование очень легкое и сложное в обслуживании. помните действенный совет - предпочитайте состав другому наследству

Похожие вопросы