Java 抽象类和toString()方法
对于如何设置TestHomeline方法,以便在使用toString()方法时正确打印,我有点困惑。现在,当我运行main方法时,它会打印“null-0”,但我希望它说的是“Math-6”。这个程序应该扩展一个抽象类。它应该说有多少页是做家庭作业的,是做什么科目的Java 抽象类和toString()方法,java,abstract,tostring,Java,Abstract,Tostring,对于如何设置TestHomeline方法,以便在使用toString()方法时正确打印,我有点困惑。现在,当我运行main方法时,它会打印“null-0”,但我希望它说的是“Math-6”。这个程序应该扩展一个抽象类。它应该说有多少页是做家庭作业的,是做什么科目的 public abstract class Homework { private int pagesToRead; private String typeHomework; { // ini
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);
}
}
派生类有自己的
类型作业
和页面阅读
字段,这些字段从未设置(即使基类碰巧有同名字段)。因此,它们保持null
和0
您应该通过公共getter方法删除这些字段并使用基类中的数据。这是因为您正在定义两个属性(其中一个属性恰好与抽象类的一个属性同名),但您没有初始化它们,而是在初始化抽象类的属性。(因此其值始终设置为其类型的默认值) 您需要从
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);
}
为什么它不起作用:
请小心,您重新声明了父类的属性typehomography
。属性会自动添加到扩展类中,因此您无需再次编写它们。通过重新说明它,您混淆了编译器,在调试中查看您的代码表明,您的
one
对象包含您的类型作业两次:
typeHomework = null // The one from the super class
typeHomework = "Math" // The one from your child class
您的方法现在使用超类中的类型作业
,因此输出为空
pagesRead
为0,因为在调用setPagesToRead(p)时,您正在将您的超类的pagesToRead
设置为6(而不是pagesRead
!)代码>
一些风格小贴士
当重写以下方法时,请使用@Override
注释:
@Override
public void createAssignment(int p) {
setTypeHomework("Math");
setPagesToRead(p);
}
实际上并不需要它,但这是一种很好的做法(代码的读者知道它会覆盖某些内容)。
在引用类的属性时,最好使用this
语句,这样就可以清楚地看到,您引用的是属性而不是局部变量:
@Override
public String toString() {
return this.typeHomework + " - " + this.pagesRead;
}
您应该使用@Override
@SLaks技术上它不是严格需要的,没有它也可以工作。但这肯定是一个好的做法。@Tunaki:是的;这就是我写评论而不是回答的原因。我应该在哪里设置它们的值?在main方法中还是在MyMath类中?@tech404:你不应该。你不应该有重复的字段,这就是为什么你有一个基类——把你的toString方法移到基类。