Java I';我在修复我的“问题”时遇到了问题;“吸气剂”;及;“二传手”;继承

Java I';我在修复我的“问题”时遇到了问题;“吸气剂”;及;“二传手”;继承,java,Java,请耐心听我说,这是我第一次用Java处理继承问题。:) 我有以下超类,用于识别船舶并返回船舶名称及其长度: public class Ship { private String name=""; private int length=0; public Ship(String name, int length) { this.setName(name); this.length = length; } public s

请耐心听我说,这是我第一次用Java处理继承问题。:)

我有以下超类,用于识别船舶并返回船舶名称及其长度:

public class Ship {

    private String name="";
    private int length=0;

    public Ship(String name, int length) {
        this.setName(name);
        this.length = length;
    }

    public static String getName() {
        return name;
    }

    public void setName(String name) {
        Ship.name = name;
    }

    public String toString() {
        return " Ship "+name+" l="+ length ;
    }

}
这是通过创建一个对象来完成的,例如:

Ship SSAnne = new Ship("S.S. Anne", 45);
然后,我有一些“子类”,它们从我的超类扩展而来,超类定义了集装箱船、油轮和游轮等对象。这是我的集装箱船的子类(除了不同的变量名外,其他类型的船舶是相同的):

这些子类的名称如下:

ContainerShip dave = new ContainerShip("Dave Oest", 100, 2000);
其中添加了一个额外变量,前两个参数是来自超类的相同变量

我的问题是“name”变量的getter和setter。当我运行代码时,它会为所有对象生成“S.S.Anne”名称,甚至是子类中的对象。我似乎无法让它“获取”我的子类的船名

有人能帮我在我的子类中正确设置getter和setter吗


@GBlodgett:

public class Ship {

    private String name="";
    private int length=0;

    public Ship(String name, int length) {
        this.setName(name);
        this.length = length;
    }

    public void getName(String name) {
        this.name = name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String toString() {
        return " Ship "+name+" l="+ length ;
    }

}

public class ContainerShip extends Ship {

    private int teu=0;

    public ContainerShip(String string, int length, int teu) {
        super(getName(), length);
        this.teu = teu;
    }

    public void getName(String name) {
        this.name = name;
    }

    public void setName(String name) {
            this.name = name;
    }

    public String toString() {
        return super.toString()+" container carrier with "+teu+" TEU";
    }

}

您已将
name
声明为
static
,这意味着类的所有实例之间只共享一个副本。您希望删除
static
关键字,然后在getter和setter中使用该关键字,该关键字引用调用该方法的对象:

 public void setName(String name) {
    this.name = name;
}
在这种情况下,
setName
方法在两个类中都是相同的,您不需要在子类中重写它


更新代码的第一个问题是,在显式调用构造函数时不能引用实例方法。不要调用
getName()
,而是将传递给构造函数的
String
参数传递给构造函数:

public SubClass(String string, int length, int teu) {
    super(string, length);
    this.teu = teu;
}
然后在
getName()
方法中,将其视为setter。您应该返回
名称
字段:

public String getName() {
    return this.name;
}
这导致了最后一个问题:您使用的是
name
的超类副本。因为您将它标记为private,所以其他类将无法访问它。您可以将
集装箱船
赋予它自己的
名称
变量,或使
船舶
中的
名称
受到保护,或再次使用
超级
,如下所示:

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

您已将
name
声明为
static
,这意味着类的所有实例之间只共享一个副本。您希望删除
static
关键字,然后在getter和setter中使用该关键字,该关键字引用调用该方法的对象:

 public void setName(String name) {
    this.name = name;
}
在这种情况下,
setName
方法在两个类中都是相同的,您不需要在子类中重写它


更新代码的第一个问题是,在显式调用构造函数时不能引用实例方法。不要调用
getName()
,而是将传递给构造函数的
String
参数传递给构造函数:

public SubClass(String string, int length, int teu) {
    super(string, length);
    this.teu = teu;
}
然后在
getName()
方法中,将其视为setter。您应该返回
名称
字段:

public String getName() {
    return this.name;
}
这导致了最后一个问题:您使用的是
name
的超类副本。因为您将它标记为private,所以其他类将无法访问它。您可以将
集装箱船
赋予它自己的
名称
变量,或使
船舶
中的
名称
受到保护,或再次使用
超级
,如下所示:

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

不能从静态方法访问实例变量

private String name="";
private int length=0;
这些是实例变量,其中方法声明为
static

public static String getName() {
在实现继承时,您应该始终记住一件关键的事情

不要在变量声明中使用静态字,也不要在方法声明中使用静态字

只有当我们处理所有的实例变量和实例(非静态)方法时,继承才会发生。所以你必须改变两件事

改变这个,

public static String getName() {
对,

类似地,您不能使用类名访问实例变量,为了引用当前对象,您可以使用
this
。因此,

public void setName(String name) {
    Ship.name = name;
}

另外,在这个构造函数中,您有一个问题

public ContainerShip(String string, int length, int teu) {
    super(getName(), length);
    this.teu = teu;
}
您没有使用作为第一个参数的
string
变量。你需要改变这个超级类

super(getName(), length);
对,

这样,无论传递给构造函数的是什么,都将传递给超类的构造函数

你应该先解决这些问题

另外,一旦您使用
ContainerShip
类创建了一个对象,它就可以从父类
Ship
访问getter/setter方法,因为您的子类将继承这些方法,称为继承。这是一个广泛的主题,随着你的继续,你将了解更多这样的结构。如果您对继承有任何疑问,请告诉我


由于您已将super类中的实例变量声明为
private
,因此子类无法直接看到您的实例变量,只能通过公共getter/setter访问它们,但如果您想直接访问它们,可以将它们声明为受保护的,并可以直接访问它们。继承是您可以从子类中的超类访问变量的原因,前提是这些变量未声明为私有
Private
表示只能在其自己的类中访问。

您不能从静态方法访问实例变量

private String name="";
private int length=0;
这些是实例变量,其中方法声明为
static

public static String getName() {
在实现继承时,您应该始终记住一件关键的事情

不要在变量声明中使用静态字,也不要在方法声明中使用静态字

只有当我们处理所有的实例变量和实例(非静态)方法时,继承才会发生。所以你必须改变两件事

改变这个,

public static String getName() {
对,

同样,您也无法访问
public static void main(String[] args) {

        ContainerShip cont = new ContainerShip("Name", 100, 4);
        System.out.println(cont.getName());
        cont.setName("new name");
        System.out.println(cont.getName());
}