Как построить объект, который имеет поле типа абстрактного класса? - PullRequest
1 голос
/ 26 декабря 2011

Итак, у нас есть класс, одно из его полей имеет тип абстрактного класса.Мы хотим написать конструктор, чтобы не было псевдонимов;то есть мы не хотим ссылаться на объект Color, который получает конструктор, а копировать его и назначать копию в наше поле Color.

class Shape {
    private Color color; /* Color is an abstract class */

    public Shape(Color c) {
       /* How do we assign a clone
          of `c` into `color`? */
    }

    /* Methods */
    ...
}

abstract class Color {
    private String colorModel;
    private float transparency;

    /* Methods */
    ...
}

Мы не можем использовать color = c.clone(), потому что компилятор выдаетследующие ошибки:

  • "Несоответствие типов: невозможно преобразовать объект в цвет."
  • "Метод clone () из объекта типа не отображается."

Итак, что является возможным решением этой проблемы?

Ответы [ 3 ]

5 голосов
/ 26 декабря 2011
  1. Color необходимо реализовать Cloneable.

  2. По Cloneable Javadoc:

    По соглашению классы, которые реализуют этот интерфейс, должны переопределять Object.clone (который защищен) с помощью открытого метода.См. Object.clone () для получения подробной информации о переопределении этого метода.

  3. Вам необходимо привести результат c.clone() обратно к Color (color = (Color)c.clone()) - хотяВаш переопределенный метод clone() для Color может сделать это для вас.

Использование Cloneable может быть не лучшим подходом для этого (см. другие ответы, публикуемые здесь) - но этодолжен предоставить то, что вы просите.

2 голосов
/ 26 декабря 2011

Напишите конструктор копирования в вашем классе Color:

abstract class Color {
    private String colorModel;
    private float transparency;

    public Color(Color c) {
        this.colorModel = c.colorModel;
        this.transparency = c.transparency;
    }
}

Я бы не рекомендовал клонировать или Cloneable.

Другая идея - сделать Color неизменным.Таким образом, вы можете безопасно делиться ссылками на цвета между Shapes;не нужно клонировать или копировать таким образом.

На случай, если неясно, вот как будет выглядеть неизменный цвет:

public final class Color {
        private final String colorModel;
        private final float transparency;

        public Color(String colorModel, float transparency) {
            this.colorModel = colorModel;
            this.transparency = transparency;
        }

        public String getColorModel() { return this.colorModel; }
        public float getTransparency() { return this.transparency; }
}
0 голосов
/ 26 декабря 2011

Если вы использовали java.awt.Color, вы могли бы использовать следующее:

this.color = new Color(c.getColorSpace(), c.getColorComponents(), c.getAlpha());

Как таковое, вам нужно будет определить конструктор копирования или метод clone() в каждом конкретном подклассевашего абстрактного класса Color.

...