需要帮助来理解java中的向下转换

时间:2016-05-02 20:59:43

标签: java casting downcast

我正在尝试(研究如何)利用创建抽象类然后再创建子类等。 我有超类

public abstract class Person {
private String name;
private String type;

public String getType() {
    return type;
}
public void setType(String type) {
    this.type = type;
}
public String getName() {
    return name;
}
public void setName(String name) {
    this.name = name;
}
}

和子类,例如:

public class Man extends Person{
    private String occupation;
    public void setOccupation(String occupation) {
    this.occupation = occupation;
    }
    public String getOccupation() {
    return occupation;
    }
    @Override
    public void setType(String type) {
        super.setType(type); 
    }
    @Override
    public String getType() {
        return super.getType(); 
    }
    @Override
    public void setName(String name) {
        super.setName(name); 
    }
    @Override
    public String getName() {
    return super.getName(); 
    }

}

和一个少年:

public class Teenager extends Person{
private String stdyPlace;
    public String getStdyPlace() {
    return stdyPlace;
}

public void setStdyPlace(String stdyPlace) {
    this.stdyPlace = stdyPlace;
}

@Override
public void setType(String type) {
    super.setType(type); 
}

@Override
public String getType() {
    return super.getType(); 
}

@Override
public void setName(String name) {
    super.setName(name); 
}

@Override
public String getName() {
    return super.getName();
}

所以,进一步我想做不同的行为取决于对象类型。我想要像:

        Person pM;

    switch (typeOfPerson){
        case "Man": pM=new Man(); pM.setOccupation("military"); ...other acts  that regards this type of object...;  break; //doesn't work
        case "Student": pM=new Teenager(); pM.setStdyPlace("Boston"); ...other acts  that regards this type of object...; break;     //doesn't work too           
    }
    pM.setName(en);
    pM.setType(tp);

但问题是, pM 的行为仅限于。我无法找到如何将其投射到我想要的类型。问题是:如何施展它?

4 个答案:

答案 0 :(得分:2)

使用instanceof运算符:

if (pM instanceof Man) {
    Man m = (Man) pM;
    //use 'Man' methods
}

这告诉您类实例是否是子类的类型。如果你不知道具体的类类型并且想要向下转换,你应该这样做。

答案 1 :(得分:2)

也许你的研究使用反射(如另一篇文章中所述)解决了你的问题,但你想要多考虑一下你的设计/抽象。

如以下帖子所述:

Object Oriented Design

Downcasting is smelly

答案 2 :(得分:1)

要做你想做的事,你需要一个正确类型的变量,以便调用正确的setter方法。

Person pM;
switch (typeOfPerson) {
    case "Man": {
        Man man = new Man();
        man.setOccupation("military");
        pM = man;
        break;
    }
    case "Student": {
        Teenager teenager = new Teenager();
        teenager.setStdyPlace("Boston");
        pM = teenager;
        break;
    }
    default:
        // You need this, otherwise pM is not definitely-assigned below
        throw new IllegalArgumentException("Unknown type of person: " + typeOfPerson);
}
pM.setName(en);
pM.setType(tp);

但是,我建议创建适当的构造函数以使其更容易。

Person pM;
switch (typeOfPerson) {
    case "Man":
        pM = new Man(en, tp, "military");
        break;
    case "Student":
        pM = new Teenager(en, tp, "Boston");
        break;
    default:
        throw new IllegalArgumentException("Unknown type of person: " + typeOfPerson);
}

答案 3 :(得分:0)

在您的示例中,pM是Person类型,它是' parent'类。在使用setOccupation()行为之前,需要使用(Man)对此字段进行类型转换。

你没有给出Student class的定义。但是即使对于Student,也不能使用Person对象中的setOccupation()方法,因为pM只是Person引用。