Java - Абстрактный класс в обычный класс - PullRequest
1 голос
/ 14 февраля 2011
public abstract class Figure
{
  private int offset;

  public Figure()
  {
    offset = 0;
  }

  public Figure(int theOffset)
  {
    offset = theOffset;
  }

  public void setOffset(int newOffset)
  {
    offset = newOffset;
  }

  public int getOffset()
  {
    return offset;
  }

  public abstract void drawHere();

  /**
   * Draws the figure at lineNumber lines down from the
   * current line.
   */

  public void drawAt(int lineNumber)
  {
    int count;
    for(count = 0; count < lineNumber; count++)
      System.out.println();
    drawHere();
  }
}

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

Этот класс расширен двумя другими классами, а затем имеет основной класс.Должен ли я пройти и изменить их тоже?

Ответы [ 7 ]

2 голосов
/ 14 февраля 2011

Если у вас есть абстрактный класс,

abstract class AbstractCar {

    float maxSpeed;
    Driver whoIsDriving;

    AbstractCar(float ms, Driver d) {
        maxSpeed = ms;
        if(!validateDriver(d)) throw new InvalidDriverException();
        whoIsDriving = d;
    }

    abstract boolean validateDriver(Driver d);

}

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

class CrappyCar extends AbstractCar {    
    boolean validateDriver(Driver d) {
        return d.hasLicense() && d.hasInsurance();
    }
}

class ExpensiveCar extends AbstractCar {
    boolean validateDriver(Driver d) {
        return d.hasLicense() && d.hasInsurance() && d.hasGoodJobInCaseHeMessesUpMyCar();
    }
}
2 голосов
/ 14 февраля 2011

Вы не должны изменять рисунок;Вы должны расширять его.

Этот класс расширен на 2 других класса, а затем имеет основной класс.Нужно ли мне проходить и изменять их тоже?

Еще одна причина, чтобы не изменять Рисунок: вы нарушите остальную часть кода.

Вы не должны изменятьчто-нибудь.Создайте новый класс, расширяющий Figure, и переопределите абстрактный метод drawHere () требуемым поведением.

0 голосов
/ 10 сентября 2012

Если класс сделан абстрактным, вы можете дать тело всем методам или ни одному из них, но если какой-либо класс расширяет абстрактный класс, он должен реализовать весь метод, который только объявлен.

0 голосов
/ 14 февраля 2011

Вы можете объявить тело метода для drawHere() (предположительно пустым, поскольку, как указывал @Frank, вы не можете иметь никакого представления о том, как нарисовать Figure) и удалить модификаторы abstract.Тогда у вас будет конкретный класс.Это означает, что кто-то может создать new Figure().Это не будет ни один из двух ваших подклассов, которые у вас сейчас есть, просто Figure.

Если такой объект (который ничего не делает, когда он вызывается для drawHere()) не будет полезен (ив частности, если вы считаете ошибочным наличие такого объекта), то вы должны сохранять класс абстрактным.Это обоснование применимо даже тогда, когда вы можете определить реализацию для каждого метода.

0 голосов
/ 14 февраля 2011

Вы правы, что удаление ключевых слов abstract и реализация абстрактных методов делают класс неабстрактным.

Однако обычно вы не хотите превращать сам класс из абстрактного в неабстрактный.Класс не является абстрактным, пока вы не добавите это ключевое слово, поэтому у вас (или кого-то еще), очевидно, была причина убедиться, что это не обычный класс, а абстрактный.

Если вы думаете об этом оченьвысокий уровень (далеко от Java), то «дерево» - это то, что вы умеете рисовать.Точно так же вы можете представить себе подкласс «Круг», для которого вы знаете, как должен выглядеть рисунок.Однако для очень общего «рисунка» вы понятия не имеете, что значит нарисовать его.

Это идея того, почему фактический рисунок остается abstract в вашем классе Figure.Следовательно, вы не должны делать Figure неабстрактным, а вместо этого сосредотачиваться на классах, которые выходят из него и делают их неабстрактными, путем реализации всех абстрактных методов из Figure.В вашем классе Tree вы знаете, что должен делать drawHere, поэтому используйте его для печати дерева.В другом классе, например Circle, вы реализуете его по-другому, но на самом деле никогда не имеет смысла реализовывать его в Figure, где вы не знаете, что рисовать.

0 голосов
/ 14 февраля 2011

Технически говоря, чтобы сделать абстрактный класс неабстрактным, вы должны:

  • Обеспечить реализацию для всех абстрактных методов
  • Поскольку теперь у вас есть действительная реализация всегоопределять, удалять все абстрактные теги

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

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

0 голосов
/ 14 февраля 2011

Если вам нужен неабстрактный класс, то вы не должны объявлять его с модификатором abstract (т.е. просто public class Figure). Не должно быть необходимости изменять какие-либо производные классы (если они сами не являются абстрактными).

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