public class Zoo{
public static void main (String[] args){
Animal animal1 = new Animal ("Giraffe", 5, 'M');
Animal animal2 = new Animal ("Lion", 10, 'F');
System.out.println (animal1.getName () + " " + animal1.getAge () + " " + animal1.getGender ());
System.out.println (animal2.getName () + " " + animal2.getAge () + " " + animal2.getGender ());
}
}
class Animal{
private int age;
private char gender;
private String name;
public Animal(){
this.name = "Giraffe";
this.age = 5;
this.gender = 'M';
}
public Animal (String name, int age, char gender){
this.name = name;
this.age = age;
this.gender = gender;
}
public void setName (String name){
this.name = name;
}
public String getName (){
return name;
}
public void setGender (char gender){
this.gender = gender;
}
public char getGender(){
return gender;
}
public void setAge (int age){
this.age = age;
}
public int getAge (){
return age;
}
}
您是否会认为此代码是正确的并且显示封装的概念? 谢谢:))
答案 0 :(得分:7)
这是学生代码。
一些建议:
答案 1 :(得分:6)
您可以考虑添加验证以确保动物无法处于无效状态。如果有人试图设定负年龄等,则抛出IllegalArgumentException
答案 2 :(得分:5)
一个问题,您不应重复System.out.println代码。您应该在Animal类中使用toString方法。
另一个问题。您可能应该拥有一个动物列表,而不是自己明确创建它们。
尝试进行这些更改,如果您遇到问题,我会给您一些建议。我不愿意提供实际的代码解决方案,因为这看起来像是我的作业。
答案 3 :(得分:3)
它似乎工作,但您并没有真正封装任何内容,因为您的所有字段都是通过设置者公开的 - 您可以致电animal1.setGender('x')
或animal1.setName(null)
,使对象处于无效状态。当然,你可以说“很好,我不会传递'x'
或null
”,但是当你在一个团队工作时这不会扩展,因为每个人对什么都有不同的假设构成“合理的”期望(例如,性别区分敏感吗?)。最糟糕的情况是,如果没有验证,每次添加一段调用getGender()
或getName()
的新代码时,如果该值不是作者预期的值,它必须处理错误的返回值或冒险。
封装的要点是你在原始字段和外部代码之间添加一个层 - 这个层负责确保对象处于有效状态,并执行需要额外了解对象内部的操作(例如作为Brian的出生日期建议 - 我喜欢这样。)
正如其他人发布的那样,一个良好的开端是为设置者添加验证(负年龄/无效名称),并使用enum
进行性别(或常数+验证,如果必须的话)。
答案 4 :(得分:3)
这种动物改变性别的可能性有多大?名称 ?也许。年龄?当然。但是我会减少代码中的可变性。这将使您的代码更可靠(特别是面对多线程,但这是一个很好的做法)。
我当然会检查无效输入。什么是有效年龄?什么是有效名称? (是否可以接受空白字符串?)。您的动物对象应该验证此类设置,因为它将包含此类有效性概念。
也许代替年龄,我会给你的动物一个出生日期(再次,不可变)。然后当你问这个动物的年龄时,它可以直接计算出来。
一个好的指导方针是,让你的对象为你做事。当对象可以派生出这样的东西时,不要设置个别属性等。
答案 5 :(得分:2)
Bloch, J., 2008. Effective Java. 2nd ed:
第15项:最小化可变性:类应该是不可变的,除非有充分的理由使它们变得可变。不可变类更容易设计和实现,不易出错,更安全。它们本质上是线程安全的,因此可以自由共享。要使Animal
类不可变,你会:
final
,使其无法延长。final
。private
。答案 6 :(得分:1)
动物不能飞,走路?动物园也需要合适的方法。
对象模型是http://en.wikipedia.org/wiki/Anemic_Domain_Model。 (这是作业,所以没关系)
答案 7 :(得分:0)
在上面的其他评论中,我认为Animal是一个非常重要的类,可以公开(讨论开放)并驻留在自己的文件中。
这会将您的“客户端”程序或可执行代码(您的Zoo类与其主要内容)从您的业务逻辑中分离出来(您现在只有一个Animal对象,但如果您成长,您必然会在应用程序中拥有更多内容它,在这种情况下,我会开始考虑在包中分离类。)
答案 8 :(得分:0)
还要确保通过参数化的方法重用真正的构造函数:
/**
* Constructs a default <tt>Animal</tt>. Current implementation
* constructs a 5 years old male Giraffe.
*/
public Animal() {
this("Giraffe", 5, 'M');
}
public Animal (String name, int age, char gender){
this.name = name;
this.age = age;
this.gender = gender;
}