简体   繁体   English

Abstract Class和toString()方法

[英]Abstract Class and toString() method

I am a little confused on how to set up the TestHomework method so that it prints properly when using the toString() method. 我对如何设置TestHomework方法有点困惑,以便在使用toString()方法时正确打印。 Right now when I run the main method it prints "null - 0" but what I would like it to say is "Math - 6". 现在,当我运行main方法时,它打印“null - 0”,但我想说的是“Math - 6”。 This program is supposed to extend an abstract class. 该程序应该扩展一个抽象类。 It is supposed to say how many pages there are for homework and for what subject. 应该说有多少页用于家庭作业和主题。

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

}

That's because you are defining the 2 properties (that one of them happen to have the same name as one of the abstract class's) but you are not initializing them, you are initializing those of the abstract class. 那是因为你定义了2个属性(其中一个属性恰好与抽象类的一个属性相同)但是你没有初始化它们,你正在初始化抽象类的属性。 (So their values is always set to their type's default) (因此,它们的值始终设置为其类型的默认值)

You need to drop those from the MyMath class, & define the toString method in your abstract class: it's the one to be used by default by its inheriting classes. 您需要从MyMath类中删除它们,并在抽象类中定义toString方法:它是默认由其继承类使用的方法。

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

Your derived class has its own typeHomework and pagesRead fields, which are never set (even though the base class happens to have fields with the same names). 派生类有自己的typeHomeworkpagesRead字段,这些字段从未设置(即使基类碰巧具有相同名称的字段)。 Therefore, they stay null and 0 . 因此,它们保持null0

You should delete those fields and use the data from the base class, via the public getter methods. 您应该通过公共getter方法删除这些字段并使用基类中的数据。

Why it doesn't work: 为什么它不起作用:

Be careful you redeclared the attribute typeHomework of you parent class. 小心你重新声明属性typeHomework你的父类。 Attributes are automatically added to your extending class so you don't have to write them again. 属性会自动添加到扩展类中,因此您无需再次编写它们。
By redeclaring it you confused the compiler, viewing your code in debug shows, that your one object contains your typeHomework twice: 通过重新声明它,你混淆了编译器,在调试节目中查看你的代码,你的one对象包含你的typeHomework两次:

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

Your method now uses the typeHomework from your super-class therefor the output is null! 你的方法现在使用你的超类中的typeHomework ,因此输出为null!

pagesRead is 0 because you are setting the pagesToRead of your super-class to 6(not pagesRead !) when calling setPagesToRead(p); pagesRead为0,因为在调用setPagesToRead(p);时,您将超类的pagesToRead设置为6(而不是pagesReadsetPagesToRead(p); .


Some style tips 一些风格提示

Use the @Override annotation when overriding methods like this: 重写这样的方法时使用@Override注释:

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

It's not really needed but it's good practice (readers of your code know that it overrides something). 它并不是真正需要的,但它是很好的做法(你的代码的读者知道它覆盖了某些东西)。

When referring to attributes of your class it's also good practice to use the this statement so it's clear, that you're referring to an attribute and not a local variable: 在引用类的属性时,使用this语句也是一种好习惯,因此很明显,您指的是属性而不是局部变量:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM