【问题标题】:Classes and Sub-classes - how do you track them?类和子类 - 你如何跟踪它们?
【发布时间】:2014-02-19 19:32:38
【问题描述】:

我和我的同学(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); 
    } 
} 

我知道它很长,但我想让你理解问题的类型...... 我不是在寻找答案,而是试图帮助我理解这些概念和思考这个问题的方法。 我们正在努力解决的主要问题是,当您扩展一个类,然后在其中调用一个方法,在子类中调用一个不同的方法等等......跟踪所有这些是很困难的。 非常感谢, 巴拉克

【问题讨论】:

  • 这些注释行是怎么回事?还请发布您对他们每个人的答案是什么?这样,您就可以比较您的答案是什么,以及如果它确实出错了,它是如何出错的。

标签: java class compilation extending


【解决方案1】:

当您的语法不正确或您没有正确实例化对象时,通常会发生编译错误。

println(Hello World) 是一个编译错误,因为 Hello 和 World 试图引用尚未实例化的变量 Hello 和 World。要解决这部分问题,您可以在上面说 String Hello = "Hello";字符串世界=“世界”;这将解决实例化错误。但这在语法上也是不正确的。如果一个函数有多个参数,它们必须用逗号分隔。要更正这部分,请使用 println(Hello + World)。这会将 2 个字符串放在一起,形成一个用于 println() 函数的参数“HelloWorld”。

a = b 没问题,因为两者都已实例化并且因为继承。将继承视为“是 a”,因此当 B 扩展 A 时,您可以说“B 是 A”。再举一个例子,一个形状(A)和一个圆(B),你可以说“圆就是一个形状”

a.equals(a1);是编译错误,因为 a1 尚未实例化。要实例化一个对象,你需要使用“new”这个词

System.out.println(a.equals(a2));是假的,因为 equals 函数首先检查 a2 是否“是”A。它是,所以它检查 x 和 y 是否是相同的值。它们不是因为 a 的 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”,就像您不能说“形状是圆形”一样,它会注意到这一点并给出运行时错误。 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 对象不同。

我希望这至少是您正在寻找的一个好的开始,我希望我的解释是有意义的。有时很难在过度解释(太多的词可能会令人困惑)和不够之间找到平衡。如果您需要更多说明,请制作一些 cmets。

已编辑 - 我在 c.m3() 部分添加了一些关于私有变量 x 的信息

【讨论】:

    【解决方案2】:

    阿海因莱因

    System.out.println(a.equals(a2));

    “instanceof”命令不允许“null”,尽管 a2 被创建为 A。 所以会返回“false”,因为“a2”为空,而不是因为它是 x 和 y 之间的理解。

    【讨论】:

      【解决方案3】:

      您可以通过两种方式学习,然后通过一种方式应用您的学习。很可能有比我列出的更多的方法,但这不是一个 stackoverflow 问题,而是一个教育学问题。

      学习方式#1

      无需使用剪切和粘贴即可创建多个类。使用不同的层次结构。使用 System.out.println 确定正在调用的方法。编写一个 main 方法来练习各种场景。尝试猜测会发生什么。然后使用现实检查它。这是基本的测试驱动开发,除了在学习环境中使用。非常适合实际的人。

      学习方式#2

      阅读类和继承。一个基本教程(非常值得)是:

      http://docs.oracle.com/javase/tutorial/java/concepts/inheritance.html
      

      您会在此站点上找到实际编写库的人在此站点上编写的材料。 一旦你通过了本教程,就会有关于继承、访问的影响、抽象、接口、类结构的 final 的高级书籍。没有一本书能够解释这些概念中的每一个。

      应用学习#1

      一旦您使用方法 1 和 2 处理了您选择的随机问题,请尝试在之前的测试中编写代码,并在您的程序告诉它们之前猜测结果。您将开始开发一种跟踪路径的技术,希望能引导您找到正确的答案。

      【讨论】:

        【解决方案4】:

        首先使用好的 IDE(Eclipse 或 Netbeans),然后尝试各种层次结构。 我建议你 O'reilly Head First Java 这本适合初学者的好书。还有食谱供练习。

        只有你才能提高自己。现在开始阅读。

        【讨论】:

          猜你喜欢
          • 2017-12-05
          • 1970-01-01
          • 1970-01-01
          • 2012-03-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-04-24
          相关资源
          最近更新 更多