2013-02-11 4 views
1

У меня есть следующая проблема. Скажем, у меня есть следующие два класса: «Велосипед на горном велосипеде». В заголовке MountainBike я заявляю: public class MountainBike extends Bicycle. Класс MountainBike добавляет два поля, не присутствующих на велосипеде. Поскольку я добавляю атрибуты один за другим (потому что я работаю с базой данных), не существует конструктора, а функция, которая устанавливает атрибуты с учетом идентификатора String и значения. Я знаю, что возможно, что не все атрибуты установлены и могут быть нулевыми, но это нормально для меня.тип литье более конкретный тип

Теперь вопрос в следующем. В данный момент я знаю, какой тип байка он есть, это одно из полей. Я хотел бы сделать следующее: как только я узнаю, что этот объект Bicycle на самом деле является MountainBike, я хотел бы передать его MountainBike: MountainBike mb = (MountainBike) bicycle, однако это приводит к запуску java.lang.ClassCastException: велосипед не может быть брошенным на MountainBike.

Я уверен, что это возможно (без использования конструктора со всем велосипедом в качестве аргумента). Как я могу это сделать?

Спасибо!

Эктор

+6

Нет, если вы получаете исключение, потому что объект, с которым вы работаете *, - это просто «велосипед». Вы не можете изменить тип объекта после создания. –

+0

Хорошо, спасибо, я попробую. Есть ли эффективный способ установить все атрибуты (у меня более ста!) От велосипеда до горного велосипеда? –

+0

Есть ли причина, по которой вы не можете создать MountainBike для начала? –

ответ

6

Как Джон Скит сказал в своем комментарии, вы не можете бросить его, если он не является MountainBike и является просто равным Bicycle. То, что вы можете сделать, это создать конструктор в MountainBike, который принимает Bicycle в качестве параметра:

public MountainBike(Bicycle bicycle) { 
    // Copy bicycle's properties 
} 

И называют это вместо:

MountainBike mb = new MountainBike(Bicycle bicycle); 

Если вы не можете изменить MountainBike класс по какой-либо причине , вы также можете создать заводской метод static:

public class MountainBikeFactory { 

    public static MountainBike createMountainBike(Bicycle bicycle) { 
     MountainBike mb = new MountainBike(); 
     // Copy bicycle's properties 
     return mb; 
    } 
} 

И назвать его :

MountainBike mb = MountainBikeFactory.create(bicycle); 

Edit: После просмотра информации вы публикуемую в качестве комментария по этому вопросу, похоже, что вы могли бы попробовать шаблон строитель. Строитель будет содержать все атрибуты как переменные (да, он будет длинным с более 100 переменными), и когда вы обнаружите атрибуты из вашего файла, установите их в построителе. Затем, в конце, когда вы вызываете метод build() строителя, разрешите ему разрешить какой тип байка создавать и использовать полиморфизм для обработки групп атрибутов w.r.t. который вы создали.

Например:

public class BikeBuilder { 
    private String model; 
    private String wheelSize; 
    private String shocks; 
    private String racingHandleBarType; 

    // returns "this" so you can chain calls, common in builders, not necessary 
    public BikeBuilder setModel(String model) { 
     this.model = model; 
     return this; 
    } 

    // Other setters 

    public Bike build() { 
     Bike bike; 
     // Determine which kind of bike it is and create it 
     if (shocks != null) { 
      bike = new MountainBike(); 
      handleMountainBike((MountainBike) bike); 
     } else if (racingHandleBarType != null) { 
      bike = new RacingBike(); 
      handleRacingBike((RacingBike) bike); 
     } else { 
      bike = new Bike(); 
     } 
     handleCommonAttributes(bike); 
     return bike; 
    } 

    // All bikes have these attributes 
    private void handleCommonAttributes(Bike bike) { 
     bike.setModel(model); 
     bike.setWheelSize(wheelSize); 
    } 

    private void handleMountainBike(MountainBike bike) { 
     bike.setShocks(shocks); 
    } 

    private void handleRacingBike(RacingBike bike) { 
     bike.setRacingHandleBarType(racingHandleBarType); 
    } 
} 

Это позволяет построить велосипед на ходу и решить его тип в конце чтения в файле, а не в начале. Он служит своего рода контейнером. Если у вас несколько типов, которые расширяют Bike, вы можете создавать для них новые методы. По крайней мере, вы начнете.

+0

Хорошо, спасибо, я попробую. Есть ли эффективный способ установить все атрибуты (у меня более ста!) От велосипеда до горного велосипеда? –

+0

Содержит ли классы следующие условные обозначения bean, такие как 'getProperty' (или' isProperty' для 'boolean') и' setProperty' для каждого поля? – Brian

+0

нет, к сожалению, нет, просто большая последовательность атрибутов String –

1

В случае, если вы сомневаетесь, что бросок может не проверить перед:

if (bike instanceof MountainBike) { 
    MountainBike mb = (MountainBike) bike 
} else { 
    String msg = "Wrong bike, expected Mountainbike but was:" + bike.getClass(); 

    System.out.println(msg); 
    throw new IllegalArgumentException(msg); 
} 
2

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

Bike bike = new MountainBike(); 
MountainBike mb = (MountainBike) bike; //works 

Bike bike = new Bike(); 
MountainBike mb = (MountainBike) bike; //ClassCastException 
Смежные вопросы