摘要 Class 和 toString() 方法

Abstract Class and toString() method

我对如何设置 TestHomework 方法以便在使用 toString() 方法时正确打印感到有点困惑。现在当我 运行 主要方法时它打印 "null - 0" 但我想它说的是 "Math - 6"。这个程序应该扩展一个抽象class。应该说作业有多少页,什么科目。

public abstract class Homework {

    private int pagesToRead;
    private String typeHomework;

    {
        // initialise instance variables
        pagesToRead = 0;
        typeHomework = "none";
    }

    public Homework(int pages, String hw) {

        this.pagesToRead = pages;
        this.typeHomework = hw;

    }

    public abstract void createAssignment(int p);

    public int getPages() {
        return pagesToRead;
    }

    public void setPagesToRead(int p) {
        pagesToRead = p;
    }

    public String getTypeHomework() {
        return typeHomework;
    }

    public void setTypeHomework(String hw) {
        typeHomework = hw;
    }

}

public class MyMath extends Homework {

    private int pagesRead;
    private String typeHomework;

    public MyMath(int pages, String hw) {
        super(pages,hw);
    }

    public void createAssignment(int p) {
        setTypeHomework("Math");
        setPagesToRead(p);
    }

    public String toString() {
        return typeHomework + " - " + pagesRead;
    }
}

public class TestHomework {

    public static void main(String[] args) {
        MyMath one = new MyMath(6, "Math");
        one.createAssignment(6);
        System.out.println(one);
    }

}

您的派生 class 有自己的 typeHomeworkpagesRead 字段,这些字段从未设置(即使基础 class 碰巧有同名的字段).因此,他们保持 null0

您应该删除这些字段并通过 public getter 方法使用基础 class 中的数据。

那是因为您正在定义 2 个属性(其中一个恰好与抽象 class 之一同名)但您没有初始化它们,您正在初始化摘要 class。 (因此它们的值始终设置为其类型的默认值)

您需要从 MyMath class 中删除那些,并在摘要中定义 toString 方法 class:它是默认使用的方法它继承了 classes.

public abstract class Homework {

    private int pagesToRead;
    private String typeHomework;

    // Same code

    // Define the toString here
    @Override
    public String toString() {
        return typeHomework + " - " + pagesToRead;
    }
}

public class MyMath extends Homework {

    // You don't need to define any extra attributes

    public MyMath(int pages, String hw) {
        super(pages,hw);
    }

    public void createAssignment(int p) {
        setTypeHomework("Math");
        setPagesToRead(p);
    }
}


public static void main(String[] args) {
    // Calls the constructor of the MyMath class, which in turn
    // invokes the constructor of its superclass, the 'Homework' class
    MyMath one = new MyMath(6, "Math");
    one.createAssignment(6);

    // Invokes the toString of the MyMath class. Since it does not have one,
    // The toString method of its superclass (Homework) is called.
    System.out.println(one);
}

为什么它不起作用:

请注意,您重新声明了父 class 的属性 typeHomework。属性会自动添加到您的扩展中 class,因此您无需再次编写它们。
通过重新声明它,您混淆了编译器,在调试显示中查看您的代码,您的 one 对象包含您的 typeHomework 两次:

typeHomework = null // The one from the super class
typeHomework = "Math" // The one from your child class

您的方法现在使用您的超级 class 中的 typeHomework 因此输出为空!

pagesRead 为 0,因为您在调用 setPagesToRead(p);.

时将超级 class 的 pagesToRead 设置为 6(不是 pagesRead!)

一些风格技巧

像这样覆盖方法时使用 @Override 注释:

@Override
public void createAssignment(int p) {
    setTypeHomework("Math");
    setPagesToRead(p);
}

这不是真正需要的,但这是一个很好的做法(您的代码的读者知道它会覆盖某些内容)。

当引用 class 的属性时,使用 this 语句也是一种很好的做法,因此很明显,您指的是属性而不是局部变量:

@Override
public String toString() {
    return this.typeHomework + " - " + this.pagesRead;
}