2009-10-30 63 views
6
class Creature {  
    private int yearOfBirth=10; 

    public void setYearOfBirth(int year) { 
     yearOfBirth = year; 
    } 

    void setYearOfBirth(Creature other) { 
     yearOfBirth = other.yearOfBirth; // is this correct it compiles fine 
    } 

    int getYearOfBirth() { 
     return yearOfBirth; 
    } 

    public static void main(String args[]) 
    { 
     Creature c = new Creature(); 
     c.setYearOfBirth(89); 

     Creature d = new Creature(); 
     c.setYearOfBirth(d); 

     System.out.println(c.yearOfBirth); 
    } 
} 

此代码中是否有任何错误?此Java代码中是否有任何错误?

“other.yearOfBirth”错了吗?我的老师说这是错误的,但它对我来说工作正常。

+1

Upvoting(不知道为什么这是downvoted) - 这似乎是一个非常好的初学者级别的问题给我。 – paxdiablo 2009-10-30 12:17:55

+3

你的老师指出你直接访问'private'变量'yearOfBirth',而不是'getYearOfBirth()'(JavaBean访问)。你能够这样做并且编译的唯一原因是因为'private'数据可以被同一类的任何实例访问。如果你试图直接从'NonCreature'类访问'yearOfBirth',编译器肯定会抛出一个错误,你将不得不使用'public'方法'getYearOfBirth()'。 – 2009-10-30 13:38:16

回答

5

您必须要求您的教员解释为什么他们认为这是错误的(它可能是一种风格问题,甚至是一种误解),所以您可以从中学习。

这个人最终会影响你的成绩。这是与他们进行积极互动的绝好机会。你的老师对你个人的教学越是牵涉,你掌握主题的机会就越好。

如果另一方面,当你被告知某些事情是错误的,你私下离开并询问一般的互联网社区,有一种风险是,你会被告知你正确,你最终会对你的老师有一种虚假的优越感,这将会适得其反。

+0

你可以问问系,或者你可以问这里数以千计的Java程序员,其中许多人会很快告诉你问题是什么,可能是你宁愿割断自己的耳朵,给他们更多:-) – paxdiablo 2009-10-30 12:26:11

+3

把它看作一种学习体验。它是否错误,因为它不能编译?或者它是错误的,因为虽然它编译,但是有一个问题。还是错误的,因为它不能解决你被要求解决的问题?有很多生产代码可用,但仍然是错误的! – 2009-10-30 12:31:14

+0

我认为这是一个好点,它也可能延伸到商业世界。有时候,你可能会被要求以某种方式去做某件事,而不是以其他方式去做,也许甚至以一种看起来不对的方式做事。这很好理解你为什么需要这样做,所以那么你知道如何让你的老板/同事/导师高兴,也知道如果他们不参与,你会怎么做。 – 2009-10-30 15:47:30

-2

这是错误的,因为您访问的是另一个对象的私有成员(您声明为private int yearOfBirth),尽管类的类型相同。您应该使用您定义的公共吸气剂来代替:yearOfBirth = other.getYearOfBirth()

+0

为什么这是错的? – Jesper 2009-10-30 12:33:10

+0

此答案也适用于来自System.out.println()调用的私人成员访问。 – highlycaffeinated 2009-10-30 12:34:16

+1

风格是有争议的,但调用这个错误是好的..错误:p – NickDK 2009-10-30 12:37:59

-2

yearofBirth是一个私有int。因此拨打other.yearOfBirth可能会失败...

+2

不,它不会,如果它在同一个班级内。 – Jesper 2009-10-30 12:33:57

+2

尽管它可能没有明确失败,但它仍然不正确。实现getter方法的关键是使用它们。 – Allyn 2009-10-30 12:51:16

7

正如您所写,它会工作,因为你发现。尽管如此,我怀疑有一个根本性的误解。

我的精神力量告诉我,你的导师预期代码更像是以下几点:

class Creature {  
    private int yearOfBirth=10; 

    public void setYearOfBirth(int year) { 
     yearOfBirth = year; 
    } 

    public void setYearOfBirth(Creature other) { 
     yearOfBirth = other.yearOfBirth; 
    } 

    public int getYearOfBirth() { 
     return yearOfBirth; 
    } 
} 

class Program { 
    public static void main(String args[]) { 
     Creature c = new Creature(); 
     c.setYearOfBirth(89); 

     Creature d = new Creature(); 
     c.setYearOfBirth(d); 

     System.out.println(c.yearOfBirth); // This will not compile 
    } 
} 

的误解是,你只创建一个分类 - 你的主应用程序类。这实际上使yearOfBirth成为您可以从主要方法访问的混合全局值。在更典型的设计中,Creature是一个完全独立于您的主要方法的类。在这种情况下,您只能通过其public界面访问Creature。您将无法直接访问其专用字段。


(请注意,以任何学究那里:是的,我知道我简化。)

+1

很好地分析。不知何故,您还展示了用于快速演示目的的简化代码的限制,该代码在其有限的环境中工作,但在实际使用中出错。类似于这些片段,为了简明而省略了关闭流,等等。 – PhiLho 2009-10-30 12:43:09

+0

是的,这是正确的我试图找出相同的,但我的问题是“yearOfBirth = other.yearOfBirth”这个工作将在类生物?它的工作正常,如果我在我的日食编号类生物编号 – Arunachalam 2009-10-30 12:44:51

+0

个人而言,我不认为'yearOfBirth = other.yearOfBirth'以客观的方式不好。一个类可以并应该理解它的内部以及如何安全地操作它们。将两个类合并为一个,并从你的主方法中引用c.yearOfBirth是我认为合理性要低得多的事情。 – 2009-10-30 13:32:17

0

没有,是一点问题都没有用了。

看,这取决于观众的意见。但是对于给定的情况,这个代码可能是完美的。

对于其他一些情况,这可能不正确。所以这取决于如何使用。

  • 直接从另一个实例访问私有成员,正确的是(并不总是可取的,虽然,例如当你继承),这就是为什么它是排在首位private。你在说“嗨,这是我的,我知道如何使用它”

  • 对其他两种方法使用default访问修饰符,表示你的意图是它们不应该被包之外的其他类使用。

我可能会补充的唯一的东西就是让课程最终完成。

final class Creature 

如果你想让它可继承你可能要检讨的yearOfBirth属性的get/set,但他们的方式很是完美的我。

NOW最重要的事情这里,是了解您的代码的每一部分做,以及它如何影响其行为。

你应该没有代码只是幸运(抱歉,我不知道这是什么正确的表达),但你应该知道你每次打字时你在做什么,你打算如何使用。

0

我看到两个“问题,”虽然我毫不犹豫地打电话给他们的错误:

  1. 你明确设置生物ç的年龄为89,然后重写,年龄与未初始化的默认(!)的生物d。如果这是你打算做的事情,那么很好,但至少你会浪费几个周期来设置一个你打算在后面抛出的值。

  2. 您可能违反了JavaBeans命名约定。

为了解释后点:很多Java库和框架(尤其是JSP)的依赖JavaBeans的治疗对象的组件。我没有深入探讨实际使用的机制,但从我读过的内容来看,它依赖于JavaBeans类的反省来推断属性和这些属性的类型。通过重载你的setter setYearOfBirth()来接受一个int和一个Creature,你可以抛弃Introspection。 (请参阅here,以便对JavaBeans进行很好的介绍。)

这不是什么大问题 - 完全有可能您不会将此类用作JavaBean,并且如果这样做可能会重构它,所以它很有用。但是,你的老师可能会喜欢的东西干净了一点,如下所示:

class Creature {  
    private int yearOfBirth=10; 

    public void setYearOfBirth(int year) { 
     yearOfBirth = year; 
    } 

    int getYearOfBirth() { 
     return yearOfBirth; 
    } 

    public static void main(String args[]) 
    { 
     Creature c = new Creature(); 
     c.setYearOfBirth(89); 

     Creature d = new Creature(); 
     c.setYearOfBirth(d.getYearOfBirth()); 

     System.out.println(c.getYearOfBirth()); 
    } 
} 

现在所有的访问yearOfBirth通过公共getter方法来,这有助于封装,并防止代码破坏,如果你的主方法转移到另一个类。 (正如Greg D正确指出的那样)。

另外,这还有一个额外的好处,那就是您的代码的目的是明确,当您开始为其他人维护和修改代码时,这变得越来越重要。

1

我没有发现任何错误。

该代码有效,因为实例或类可以访问同一类的其他实例的私有成员。这是设计。

+0

问题不在于它是否起作用 - 显然,它起作用。问题在于是否有更好的(也就是说更脆弱)的方式来设计这个类。您可以只使用一个类来编写整个Web服务器,并公开所有成员变量。你甚至可以让它工作,但是最终的应用可能很难维护,以至于整个事情可能是“错误的”,而不是功能上的,但是因为你的代码遵循“大泥潭”反模式。 – rtperson 2009-10-30 14:35:56

+0

类必须能够相信自己才能正确处理自己的私有成员,即使这些成员属于不同的实例。这并非天生脆弱,特别是如果操作是只读的。如果你遇到一个你觉得这个问题有问题的情况,你有一个班级太大了,应该把它分开。 – 2009-10-30 19:16:23

+0

“可以访问同一类的其他实例的私有成员” - 实际上我不知道,尽管我经常使用Java。它似乎很肮脏:-) +1为扩大我的知识。 – paxdiablo 2009-10-30 22:48:52