我和我的同学(第一年CS)正在努力解决问题类和子类。 我们有一个测试,其中一个问题检查对类,子类,法律和非法投射之间的理解等。 问题通常是一样的: 您将获得2-3个名为A,B,C的类,其中一些扩展其他类,然后是不同的构造函数和10-15个非常令人困惑的代码行,我们需要告诉它们是否会导致其中一个以下: 1.运行时错误。 2.编译错误。 3.将运行(将打印出来的内容)。
测试仅限纸质。 问题是,你有跟踪不同类和变量的方法吗?是否有一个教这些科目的网站?
这是上一次测试的问题: 以下哪行代码会导致编译错误,运行时错误以及将要打印的内容:(我添加了解决方案)
A a = new A(1,2);
B b = new B(1,2,3);
C c = new C(1,2);
A bb = (A) b;
A a1;
A a2 = null;
System.out.println("Hello world"); //"Hello World
System.out.println(Hello world); //Compilation error
System.out.println(1/0); //Runtime Error
a = b; //Will run with no errors
a.equals(a1); //compilation error
System.out.println(a.equals(a2));//will print false.
System.out.println(b.equals(c)); //will print true.
B aa = (B) a; //runtime error.
C bbb = (C) bb; //runtime error
C ccc = (C) b; //compilation error
a.m1(); //will print m2
b.m1(); //will print 3
c.m3(); //will print 2.
a.m5(); //will print false
A类:
public class A {
private int x;
public int y;
private C c = null;
public A(int x,int y){
this.x = x;
this.y = y;
}
public void m1() { m2();}
public void m2() {
System.out.println("m2");
}
public void m3(){ m4(); }
public void m4() {
A tmp = new B(1,2,3);
System.out.println(tmp.y);
}
public void m5() {
System.out.println((new C().equals(c)));
}
public boolean equals(Object other) {
if(!(other instanceof A)) return false;
return (((A)other).x==x &
((A)other).y==y);
}
}
B组:
public class B extends A {
public int y;
public B(int x, int y1, int y2){
super(x,y1);
this.y = y2;
}
public void m2(){
m3();
}
public void m4() {
B temp = new B(1,2,3);
System.out.println(temp.y);
}
}
C类:
public class C extends A {
public int y;
public C(int x, int y){
super(x,y);
this.y = y;
}
public C(){
this(0,0);
}
}
我知道它很长,但我希望你能理解问题的类型...... 我不是在寻找答案,试着帮助我理解这些概念以及思考这个问题的方法。 我们正在努力解决的主要问题是,当你扩展一个类,然后在其中调用一个方法时,它会在子类中调用一个不同的方法,因此......跟踪所有这些困难。 非常感谢, 巴拉
答案 0 :(得分:1)
当您的语法不正确或者您没有正确实例化对象时,通常会发生编译错误。
println(Hello World)是一个编译错误,因为Hello和World正在尝试引用尚未实例化的变量Hello和World。要解决这个问题,在它上面就可以说String Hello =“Hello”; String World =“世界”;这将解决实例化错误。但这在语法上也是不正确的。如果函数采用多个参数,则必须用逗号分隔。更正此部分,println(Hello + World)。这将2个字符串组合在一起,形成一个参数“HelloWorld”,用于println()函数。
a = b是好的,因为两者都已实例化并且由于继承。认为继承是“是一个”,所以当B延伸A时,你可以说“B是A”。使用另一个例子,形状(A)和圆形(B)你可以说“圆形是一个形状”
a.equals(A1);是一个编译错误,因为a1尚未实例化。要实例化一个对象,你需要使用“new”一词
的System.out.println(a.equals(A2));是假的,因为等于函数首先检查a2“是否是”A.它是,所以它检查x和y是否是相同的值。它们不是因为设置了x和y,而a2只是一个空对象。
的System.out.println(b.equals(C));是的,因为再次,“c是A”,所以它检查b和c的x和y。他们是1和2,所以这是真的。
B aa =(B)a; a已经实例化,它在语法上是正确的,所以它通过编译。但是你可以说“B是A”而不是“A是B”,就像你试图运行时不能说“Shape is a Circle”一样,它注意到并给出了运行时错误。 C bbb =(C)bb;因为bb是一个A对象,所以是一样的。
a.m1(); //将打印m2。函数m1()执行的第一个(也是唯一一个)命令是调用m2()。这打印“m2”。所以当你调用a.m1()时,它与直接调用a.m2()相同。
b.m1(); //将打印3.因为B覆盖了m2()和m4()函数,所以它调用m1() - > m2() - > m3() - > m4()和m4()创建一个变量并打印其y值。 B(x,y1,y2)的构造函数设置x = x; y = y1; (来自super(x,y1)函数)但随后用y2覆盖y。
c.m3(); //将打印2.这很令人困惑。就像最后一个一样,这个叫m3() - > M4()。因为C不会覆盖它们中的任何一个,所以它使用A定义的那个.A的m4()从新的B(1,2,3)创建一个A. B对象的y值被y2(3)覆盖,但由于A的x值是私有的,因此B构造函数无法触及A的x值,因此无法覆盖它。
a.m5(); //将打印false与“System.out.println(a.equals(a2));”相同以上。 A的c值为null,C有一个没有参数C()的构造函数,它调用C(0,0)。 null C与已实例化的C对象不同。
我希望这至少是你正在寻找的一个良好的开端,我希望我的解释是有道理的。有时很难找到过度解释之间的平衡(有太多的词可能令人困惑)而且还不够。如果您需要更多说明,请发表一些意见。
已编辑 - 我在c.m3()部分
中添加了一些关于私有变量x的内容答案 1 :(得分:1)
Aheinlein
的System.out.println(a.equals(A2));
“instanceof”命令不允许“null”,尽管a2创建为A. 所以“假”会回归,因为“a2”是空的,而不是因为它的x和y之间的理解。
答案 2 :(得分:0)
您可以通过两种方式学习,然后通过一种方式学习。很可能有比我列出的更多的方法,但这不是一个stackoverflow问题,而是教育学的问题。
学习方式#1
创建多个类而不使用剪切和粘贴。使用不同的层次结构。使用System.out.println确定要调用的方法。写一个主要方法来练习各种场景。试图猜测会发生什么。然后使用现实检查它。这是基本的测试驱动开发,除了在学习环境中使用。对于实际的人来说非常有效。
学习方式#2
阅读类和继承。一个基本的教程(非常值得):
http://docs.oracle.com/javase/tutorial/java/concepts/inheritance.html
您可以找到实际编写库的人在本网站上撰写的材料。 一旦通过本教程,就会有关于继承,访问,抽象,接口,最终对类结构的影响的高级书籍。没有一本书能够解释这些概念中的每一个。
申请学习#1
一旦您使用方法1和2接近您选择的随机问题,请尝试在先前的测试中编写代码并在程序告诉它们之前猜测结果。您将开始开发一种跟踪路径的技术,希望能够引导您找到正确的答案。
答案 3 :(得分:0)
首先使用好的IDE(Eclipse或Netbeans)然后尝试各种层次结构。 我建议你O'reilly Head First Java这是一本适合初学者的好书。还有练习本。
只有你才能提高自己。现在开始阅读。