我创建了一些具有继承概念的类,我的应用程序有主类,即模块模件(与模块相对应),还有其他一些类,分别是moduloLedRGBModuloSwitchModuloDimmer,这3个类所有这些都扩展了类模,该类只具有模块的公共参数,例如id,名称,模块类型和ipAdress。但是,当我尝试将模块转换为这3个子类之一时,出现了异常,提示我无法将Modulo转换为ModuloSitchModuloLedRGB

这是我得到错误的地方:

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;
    }

}


这是模类。

这是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;
    }
    }


我为何会收到此例外的任何想法?既然孩子扩展了主要课程,我想我应该可以把它放下,不是吗?

最佳答案

根据评论,您似乎误解了投射的本质。

当你说

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(如果不为null)是Modulo;它可以是ModuloModuloLedRGBModuloSwitch类的对象。因此,在运行时,代码将检查其实际指的是哪种对象。由于上面的示例将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中没有这样的东西。

08-17 21:20