Я создал несколько классов с концепцией наследования, у меня есть основной класс для моего приложения, который называется модулем, который соответствует модулю, а также некоторые другие классы, называемые moduloLedRGB
, ModuloSwitch
и ModuloDimmer
, все эти 3 класса расширяют класс по модулю, который имеет только общие аргументы для модулей, такие как id, name, Module type и ipAdress. Но когда я пытаюсь преобразовать модуль в один из этих трех дочерних классов, я получаю исключение, в котором говорится, что я не могу преобразовать Modulo
в ModuloSitch
или ModuloLedRGB
...
Вот где я получаю ошибку:
switch (modulo.getModulo()){
case "RGB":
ModuloLedRGB rgb = (ModuloLedRGB) modulo;
rgb.setProgress(c.getDouble(c.getColumnIndex("progress")));
rgb.setProgressRed(c.getDouble(c.getColumnIndex("progressRed")));
rgb.setProgressGreen(c.getDouble(c.getColumnIndex("progressGreen")));
rgb.setProgressBlue(c.getDouble(c.getColumnIndex("progressBlue")));
break;
case "Dimmer":
ModuloDimmer dimmer = (ModuloDimmer) modulo;
dimmer.setProgress(c.getDouble(c.getColumnIndex("progress")));
break;
case"Switch":
ModuloSwitch sw = (ModuloSwitch) modulo;
break;
Он говорит, что я не могу привести по модулю, что объект соответствует классу Modulo, к ModuloRGB. getModulo возвращает строку, в которой говорится, что это за модуль.
package br.com.andrey.projetointegradoapp;
/**
* Created by andrey on 04/08/2016.
*/
public class Modulo {
private long id;
private String nome;
private String ModuleIpAdress;
private String modulo;
public String getModulo() {
return modulo;
}
public void setModulo(String modulo) {
this.modulo = modulo;
}
public String getModuleIpAdress() {
return ModuleIpAdress;
}
public void setModuleIpAdress(String moduleIpAdress) {
ModuleIpAdress = moduleIpAdress;
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getNome() {
return nome;
}
public void setNome(String nome) {
this.nome = nome;
}
}
Это класс Modulo.
А это класс ModuloLedRGB:
package br.com.andrey.projetointegradoapp;
/**
* Created by andrey on 16/12/2016.
*/
public class ModuloLedRGB extends Modulo {
private double progress;
private double progressRed;
private double progressGreen;
private double progressBlue;
public double getProgressRed() {
return progressRed;
}
public void setProgressRed(double progressRed) {
this.progressRed = progressRed;
}
public double getProgress() {
return progress;
}
public void setProgress(double progress) {
this.progress = progress;
}
public double getProgressGreen() {
return progressGreen;
}
public void setProgressGreen(double progressGreen) {
this.progressGreen = progressGreen;
}
public double getProgressBlue() {
return progressBlue;
}
public void setProgressBlue(double progressBlue) {
this.progressBlue = progressBlue;
}
}
Есть идеи, почему я получаю это исключение? поскольку потомок расширяет основной класс, я думаю, что смогу его отбросить, не так ли?
1 ответ
Судя по комментариям, вы неправильно понимаете природу кастинга.
Когда ты говоришь
class Modulo { ... }
class ModuloLedRGB extends Modulo { ... }
Создание подкласса определяет отношение is-a ; каждый ModuloLedRGB
также является Modulo
. Но это не работает в обоих направлениях.
Если вы создаете объект с
new Modulo()
Тогда это Modulo
, но не ModuloLedRGB
. Если вы создадите его с помощью
new ModuloLedRGB()
Это одновременно ModuloLedRGB
и Modulo
. Сказать, что это Modulo
, означает, что вы можете присвоить ему переменную типа Modulo
или использовать его как параметр Modulo
:
ModuloLedRGB x = new ModuloLedRGB();
Modulo y = x; // this is legal, but the object's class doesn't change
y
- это ссылка на объект ModuloLedRGB
. Но обратите внимание, что хотя y
объявлен как Modulo
, он по-прежнему относится к тому же объекту, чей класс - ModuloLedRGB
, потому что таким образом создается объект.
Вот почему вы можете использовать понижающее приведение. Скажем, вы позже используете выражение
(ModuloLedRGB)y
На данный момент компилятор знает только, что y
(если не ноль) является Modulo
; это может быть объект класса Modulo
, ModuloLedRGB
, ModuloSwitch
или что-нибудь еще. Таким образом, во время выполнения код проверяет, на какой именно объект он ссылается. Поскольку в приведенном выше примере y
задано как объект, созданный как ModuloLedRGB
, приведение выполняется успешно. Но если y
был установлен на какой-то другой объект, который не был ModuloLedRGB
, приведение выдает исключение.
Это приведение не меняет объект и не создает новый объект. Он просто говорит: «Убедитесь, что объект относится к классу ModuloLedRGB
, а затем обработайте его как ModuloLedRGB
, чтобы мы могли получить доступ к методам и переменным экземпляра, которые относятся к ModuloLedRGB
».
Однако похоже, что вы пытаетесь преобразовать объект, изменив его класс. Вы создали объект, класс которого равен Modulo
, и вы пытаетесь создать какой-то новый объект с классом ModuloLedRGB
. Вы не можете этого сделать с гипсом. Если у вас есть Modulo
и вы хотите создать ModuloLedRGB
, вам нужно будет где-нибудь создать новый объект с new ModuloLedRGB()
. Один из распространенных способов сделать это - написать конструктор:
class ModuloLedRGB extends Modulo {
public ModuloLedRGB(Modulo m, maybe other parameters) {
// copy the instance variables from "m"
this.field = m.field;
this.anotherField = m.anotherField;
// set the new instance variables
this.newField = maybe a parameter or some other computation;
...
}
Или напишите статический фабричный метод для создания нового ModuloLedRGB
из Modulo
. Но вам придется его создать, и вам нужно будет написать код для его создания. Вы не можете "преобразовать" его из Modulo
. В Java такого нет.
ModuloLedRGB
, ModuloSwitch
или другие объекты других подклассов. Modulo[]
, или Set<Modulo>
, или List<Modulo>
, или другая коллекция часто будет иметь элементы разных подклассов Modulo
- вот как работает Modulo
. Но вы должны создавать их с помощью правильного класса при их создании. Это нет типичного объектно-ориентированного подхода для создания объектов базового класса (Modulo
) и попытки получить реальный класс позже ...
Modulo
абстрактным классом, чтобы вы не могли прямо сказать new Modulo()
но вам потребуется создать с помощью подкласса.
Похожие вопросы
Новые вопросы
java
Java — это высокоуровневый объектно-ориентированный язык программирования. Используйте этот тег, если у вас возникли проблемы с использованием или пониманием самого языка. Этот тег часто используется вместе с другими тегами для библиотек и/или фреймворков, используемых разработчиками Java.
modulo
? Если он был создан с помощьюnew ModuloLedRGB()
(или подклассаModuloLedRGB
), вы можете преобразовать его вModuloLedRGB
. В противном случае вы не сможете этого сделать, и попытка приведения приведет к исключению во время выполнения.modulo
на"RGB"
? Я не нашел этого в показанном вами коде.