Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/314.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java I';我很难弄清楚如何覆盖部分“文件”;toString";超类中的方法(多态性)_Java - Fatal编程技术网

Java I';我很难弄清楚如何覆盖部分“文件”;toString";超类中的方法(多态性)

Java I';我很难弄清楚如何覆盖部分“文件”;toString";超类中的方法(多态性),java,Java,我有一个超类“容器”和一个子类“瓶子”。子类“瓶子”还有两个子类“玻璃瓶”和“塑料瓶” 我想要以下输出: 这个容器的容积是1 这个瓶子的容积是1,里面装的是果汁 这款绿色玻璃瓶的容量为2,内含果汁 这个白色玻璃瓶的容量是1,里面装着啤酒 另一个瓶子的容量是2,里面装可乐 此PET瓶的体积为1,含有牛奶 但是,我在重写每个类中不同的toString方法时遇到问题 这是我的输出: 这个容器的容积是1 这个瓶子这个容器的容积是1,里面有果汁 这个绿色玻璃瓶这个瓶子这个容器有两个容量,包含 果汁 这个白

我有一个超类“容器”和一个子类“瓶子”。子类“瓶子”还有两个子类“玻璃瓶”和“塑料瓶”

我想要以下输出:

这个容器的容积是1

这个瓶子的容积是1,里面装的是果汁

这款绿色玻璃瓶的容量为2,内含果汁

这个白色玻璃瓶的容量是1,里面装着啤酒

另一个瓶子的容量是2,里面装可乐

此PET瓶的体积为1,含有牛奶

但是,我在重写每个类中不同的toString方法时遇到问题

这是我的输出:

这个容器的容积是1

这个瓶子这个容器的容积是1,里面有果汁

这个绿色玻璃瓶这个瓶子这个容器有两个容量,包含 果汁

这个白色玻璃瓶这个瓶子这个容器的容积是1,里面装啤酒

这个瓶子这个瓶子这个容器的容积是2,里面装可乐

这个PET瓶这个瓶子这个容器的体积是1,里面装着牛奶

从第二个输出中可以看到,它插入了“This-vessel”,因为该字符串是我正在调用的“toString”方法的一部分,所以它在那里是有意义的。但是,我希望java在调用
super.toString()
时省略超类的这一部分,只包括其他必要的部分。以下是我的超类和子类:

public class Vessel {

    private int volume=0;

    public Vessel(int volume) {
        this.volume = volume;
    }

    public String toString() {
    return "This vessel has a volume of "+volume;
    }

}

public class Bottle extends Vessel {

    private String content="";

    public Bottle(int volume, String content) {
        super(volume);
        this.setContent(content);
    }

    public String getContent(String content) {
        return this.content = content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public String toString() {
        return "This bottle "+super.toString()+" and contains "+content;
    }

}

public class GlasBottle extends Bottle {

    private String color="";

    public GlasBottle(int volume, String content, String color) {
        super(volume, content);
        this.setColor(color);
    }

    public String getColor(String color) {
        return this.color = color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public String toString() {
        return "This "+color+" glas bottle "+super.toString();
    }

}

public class PlasticBottle extends Bottle {

    private String material="";

    public PlasticBottle(int volume, String content, String material) {
        super(volume, content);
        if(material != "PET") {
            this.material = "OTHER";
        }else {
            this.setMaterial(material);
        }
    }

    public String getMaterial(String material) {
        return this.material = material;
    }

    public void setMaterial(String material) {
        this.material = material;
    }

    public String toString() {
        return "This "+material+" bottle "+super.toString();
    }

}

我想您可以通过使用
toString()
父类的卷信息来避免重复:

公共字符串toString(){ return“本船容积”+容积; }

但它不会以这种方式给出预期结果:

public String toString() {
    return "This bottle "+super.toString()+" and contains "+content;
}
它只会在构建字符串中混合当前类和父类信息

在子类中您需要的是:

public String toString() {
    return "This bottle has a volume of " + getVolume() + " and contains "+content;
}
在这种情况下,您应该引入一个getter来从子类访问
volume

请注意,为了避免重复并保持
字段
私有
,您还可以在子类中编写如下内容:

public String toString() {
    return "This bottle" + toStringVolume() " and contains " + content;
}
并在父类中定义:

public final String toStringVolume(){
   return "has a volume of " + volume;     
}
但它真的有价值吗?
它在阅读中创造了一些间接的东西,但价值不大

您想要的是“覆盖”而不是覆盖

首先,将
getVolume()
方法添加到顶级
Vesser
类中,因为您的
私有的

您可以简单地将更改的部分作为单独的方法放置。 因此,在
瓶子中
放置一个如下方法:

protected String getBottleType() {
  return "bottle";
}
public String toString() {
    return "This " + getBottleType() + " has a volume of " + getVolume() + " and contains " + content;
}
并将您的
更改为字符串()
,如下所示:

protected String getBottleType() {
  return "bottle";
}
public String toString() {
    return "This " + getBottleType() + " has a volume of " + getVolume() + " and contains " + content;
}
然后,在
battle
的每个子类中,您只需重写
getBattleType()
。例如,在
玻璃瓶
中,您只需执行以下操作:

@Override
protected String getBottleType() {
 return color + " glass bottle";
}
然后,您实际上可以省略子类的
toString()
,除非您希望更改句子

我希望java在调用
super.toString()
时省略超类的这一部分,只包括其他必要的部分

您知道
super.toString()
返回您定义的整个字符串。“其他必要的部分”是只有你知道的东西。您可以解析
super.toString()
来提取所需的部分,但这既繁琐又愚蠢


一种合理的方法是通过公共getter访问父类的属性,并为每个子类构造一个唯一的
字符串,忽略父类如何表示自己。

我认为最简单的方法如下: 从GlasBottle和PlasticBattle中删除toString方法,引入“vesselQualifier”(例如颜色、材质)的概念,并在Vessel和Battle中重写toString方法,如下所示,这些方法在运行时从相应的子类中获得成对的向下类名。为了简洁起见,我删除了所有其他无关的代码

public class Vessel {
    protected String vesselQualifier() {
        return null;
    }
    public String toString() {
        String[] classNameParts = this.getClass().getCanonicalName().split("\\.");
        return "This "
                +(vesselQualifier()==null?"":(vesselQualifier()+" "))
                +classNameParts[classNameParts.length-1]+" has a volume of " + volume;
    }
}

public static class Bottle extends Vessel {
    public String toString() {
        return super.toString() + " and contains " + content;
    }
}

public static class GlasBottle extends Bottle {
    @Override
    protected String vesselQualifier() {
        return color;
    }
}

public static class PlasticBottle extends Bottle {
    @Override
    protected String vesselQualifier() {
        return material;
    }
}

您要做的是使用包含对象名称的字段,如String thisName=“瓶子”。然后在你的toString中,你只需要返回“This”+thisName+“whatever”@WoeIs为
卷添加公共getter