Расширить объект и наследовать все переменные - PullRequest
3 голосов
/ 18 июля 2010

Допустим, у меня есть объект класса Car с примерно 30 переменными в диапазоне от максимальной скорости до цвета.Я хочу сделать объект MyCar (класс MyCar extends Car), который в основном является тем же самым, за исключением того, что он хранит некоторую дополнительную информацию.

Я не могу сразу создавать объекты MyCar (так как из тысячТолько несколько объектов из автомобилей станут объектами MyCar), если я не оставлю дополнительные поля пустыми, но это не кажется слишком профессиональным.И при этом не создается ни конструктор, который принимает 30 аргументов, ни установка 30 аргументов через вызовы методов.

Итак, есть ли способ легко наследовать все переменные из объекта суперкласса?

PS:Моя программа не об автомобилях, но я подумал, что это будет более простой пример.

РЕДАКТИРОВАТЬ

Спасибо за ответы.Все они полезны для моей программы, но не для этой конкретной проблемы.Строители не кажутся выгодными, потому что эти машины не имеют значений по умолчанию для своих переменных.Каждый раз, когда производится автомобиль, все переменные заполняются (что необходимо для создания своего рода «фактологического бюллетеня»).

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

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

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

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

Спасибо за помощь!

PS: Я просто думаю, возможно, я мог бы бросить все переменные в HashMap.Таким образом, я мог получить к ним доступ, используя .get (varname), и мне нужно было только передать одну переменную HashMap в подкласс.Недостатком является то, что мне придется много разыгрывать, поскольку переменные представляют собой смесь строк, целых, двойных чисел и т. Д. Как вы думаете, это приемлемый стиль кодирования?

Ответы [ 7 ]

4 голосов
/ 18 июля 2010

Effective Java 2nd Edition, Item 2: Рассмотрим конструктор, когда сталкиваемся со многими параметрами конструктора

И ни один не создает конструктор, который принимает 30 аргументов, или установка 30 аргументов через метод вызовов.

Если вы сталкиваетесь с конструктором с слишком большим количеством параметров , тогда вы можете взглянуть на: Pattern Builder . Идея состоит в том, чтобы установить только то поле, которое вы хотите / знаете в builder , не беспокоясь о необязательных или тех, которые вы хотите использовать default значения, затем вызов build() для создания фактического объекта. См. Примеры Java в этой статье.

Как только вы настроите этот шаблон, вы можете построить Автомобили таким образом (обратите внимание на чистую структуру):

Car car = new Car.Builder(required_param1, required_param2)
                 .color(RED) // optional params
                 .topSpeed(300)
                 .zeroToHundred(2)
                 .build();
1 голос
/ 18 июля 2010

ОП здесь.

Я понимаю, что это похоже на лень.Но у меня уже есть это работает, вручную копируя 30 переменных в конструкторе.Я знаю, что это не такая уж большая задача.

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

Но если на самом деле нет другого способа, кроме как скопировать переменные (или переопределить все методы get & set), тогда мне не нужно искать какие-либодалее.

Излишне говорить, что все ответы в этой теме дали мне новое понимание.Спасибо, ребята.

1 голос
/ 18 июля 2010

Я не могу сразу создать объекты MyCar (поскольку из тысяч объектов Car только несколько станут объектами MyCar),

Итак, вы получитемного объектов типа Car, некоторые из которых вы хотели бы, во время выполнения, «продвигать» до типа SpecialCar?

У SpecialCars точно такой же интерфейс, как у Cars?Возможно, вы захотите прочитать шаблон письма-конверта Коплиена, это способ «изменения» типа объекта во время выполнения.Конечно, объект не меняет тип;вместо этого другое «Письмо» входит в существующий «Конверт».Конверт - это дескриптор, на который ссылаются другие коды, но вызовы метода в Конверте делегируются в Letter:

 class CarEnvelope { // an envelope
    Car c ; // the letter
    CarEnvelope( Car c ) { this.c = c ; }
    int someMethod() { 
      return c.someMethod(); // delegate 
    }
    void promoteToSpecialType() {
       if( ! c.isSpecialCar() ) {
          c = new SpecialCar( c ) ;
    }
 }

 class Car {
   Car() {}
   int someMethod() { do Car stuff }
   boolean isSpecial() { return false; }
 }

 class SpecialCar extends Car {
   SpecialCar( Car c ) { /*copy c's attributes...*/ } 
   int someMethod() { do SpecialCar stuff}
   boolean isSpecial() { return true; }
 }

 CarEnvelope c = new CarEnvelope( new Car() ) ;
 // do stuff with c
 c.someMethod(); // indirectly calls Car.someMethod();
 // promote
 c.promoteToSpecialType();
 c.someMethod(); // indirectly calls SpecialCar.someMethod
1 голос
/ 18 июля 2010

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

0 голосов
/ 19 июля 2010

Мы можем создать интерфейс ICar, который имеет все методы получения и установки для всех 30 столбцов.Автомобиль может реализовывать ICar и может содержать все 30 полей с соответствующими им геттерами и сеттерами.MyCar также может реализовывать ICar и использовать композицию.Он представляет методы Car в качестве методов делегатов (которые могут автоматически генерироваться в IDE, например, eclipse)

public interface ICar {
// getter and setter methods
}

public Car implements ICar {
 private String color;
 // getters and setters for each of the fields
}

public MyCar implements ICar {
 private Car car;
 public MyCar(Car car){
  this.car = car;
 }
 public String getColor() {
  return car.getColor();
 }
}

Все потребители могут затем использовать интерфейс ICar для своих манипуляций.Будет ли это работать?

0 голосов
/ 18 июля 2010

Я не понимаю. Что не так с обычным наследованием?

class Car {
    private int attributeOne;
    .....
    private boolean attrbuteThirty;

    public void methodOne(){...}
    ...
    public void methodThirty(){...}
}

А потом просто подкласс:

 class SubCar extends Car {
     private int extraAttribute;
  }

Все 30+ атрибутов и методов уже унаследованы, вот что такое extends.

Если вам нужно создать новый объект на основе данных существующего, , но вы сопротивляетесь code it! (¬¬), тогда вы можете просто создать небольшой скрипт для создания кода для вас. Это очень просто. Вы копируете / вставляете сгенерированный код, и все готово.

Если вы не хотите делать это, потому что вы не хотите дублировать данные, вы можете переопределить интересные методы и делегировать код оригиналу, это то, что шаблон проектирования Decorator это все о:

class SubCar extends Car {
    private Car wrapped;
    private String extraAttribute;
    public SubCar( Car original, String newAttributeOne ) {
        wrapped = original;
        this.extraAttribute = newAttributeOne;
   }

    public void someMethod() {
        wrapped.someMethod();
    }
    public String getName() { return wrapped.getName();  }
    ... and so on
    // new method 
    public String extraAttribute() { return extraAttribute; }
}

Таким образом, вы не будете дублировать данные, а просто украсите их.

0 голосов
/ 18 июля 2010

У меня такое ощущение, что вы ищете понятие шаблона; например,

public class Car {
   private final int attr1;
   private final int attr2;
   ...

   public Car() {
       super();
   }

   /* copy constructor */
   public Car(Car template) {
       this.attr1 = template.attr1;
       this.attr2 = template.attr2;
       ...
   }

   /* setters and getters */
}

Тогда ...

Car myTemplate = new Car();
myTemplate.setAttr1(3);
myTemplate.setAttr2(11);
...

Car car1 = new Car(myTemplate);
car1.setAttr1(4);
Car car2 = new Car(myTemplate);
car1.setAttr1(5);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...