Возможно ли иметь специализированные параметры в переопределенных методах?

StackOverflow https://stackoverflow.com/questions/820344

  •  03-07-2019
  •  | 
  •  

Вопрос

Допустим, у меня есть абстрактный родительский класс под названием "shape", и что существует несколько подклассов (треугольник, квадрат, круг...).Я хочу определить абстрактный метод в родительском классе "shape", который должны реализовывать все подклассы, давайте назовем его "draw".Таким образом, все подклассы shape должны предоставлять метод "draw()".Но метод draw принимает параметр типа "Stencil", и не каждый подкласс shape может использовать только любой трафарет...

Итак, существует один абстрактный класс "shape", несколько подклассов shape и несколько трафаретов.Мне нужен метод рисования, определенный в классе shape.Квадрат может использовать Трафарет1, а круг - Трафарет2.

Я предполагаю, что дженерики справились бы с этой задачей, но я не уверен.Каждый подкласс shape должен определять метод рисования с помощью определенного шаблона, поскольку эти классы используются и другими классами, и компилятор должен заставить всех программистов вызывать методы рисования с использованием шаблона, который поддерживается этим классом.Мы не можем определить абстрактный метод, такой как "public abstract void draw (трафареты)", потому что тогда программист мог бы передать любой трафарет классу square, тогда как класс square поддерживает только "Stencil1"

Есть какие-нибудь идеи?

Обновление1: Следует добавить, что классу shape все равно, какой трафарет используется подклассом, но поскольку подклассы используются и в других классах, важно, чтобы метод draw был определен так, чтобы компилятор принимал только поддерживаемый трафарет.

Это было полезно?

Решение

public abstract class Shape<S extends Stencil>
{
   public abstract void draw( S stencil );
}

public class Square extends Shape<Stencil1>
{
   public void draw( Stencil1 stencil )
   {
     stencil.letsdo();
     stencil.some();
     stencil.drawing();
   }
}

public class Circle extends Shape<Stencil2>
{
   public void draw( Stencil2 stencil )
   {
      stencil.some();
      stencil.more();
      stencil.drawing();
   }
}

Другие советы

Я думаю, вам, вероятно, следует пересмотреть свой первоначальный дизайн.

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

Если вы хотите, чтобы это было зафиксировано во время компиляции, на ум приходят следующие варианты:

  • Создайте набор абстрактных трафаретов.Особенно, если вы считаете, что можете сгруппировать их.Поэтому, если у вас будет несколько "квадратных" трафаретов, создайте абстрактный тип SquareStencil и извлеките из него конкретные экземпляры.Вы даже можете создать их как подмножество абстрактного класса Stencils .
  • Перегрузите метод рисования.Нет необходимости в том, чтобы это было общим.Позвольте компилятору помочь вам, выбрав правильный метод для выполнения задания.

Определите абстрактный трафарет и позвольте конструктору подкласса решить, какой класс трафарета использовать.

private Stencil s;

public void draw(){
   privateDraw(s)
}

private abstract void privateDraw(Stencil s);
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top