请举例说明如何使用封装来演示代码可维护性?
为什么要为此使用 getter 和 setter 方法?
基本思想是为您的类的用户提供所有必要的操作(类方法),而不是让他完全访问数据(类变量)。这种技术可以防止对类变量的任何无意修改和数据不一致。例如:假设您有一个名为 Student 的课程
Class Student {
private:
int id;
string name;
public:
SetStudenDetails( int i, string n);
PrintStudentDetails();
};
使用 Get 方法可以确保类的用户同时提供名称和 ID。
我建议你阅读 Timothy Budd 的《面向对象编程》一书。
想象一下,我们都为同一个项目工作,首先你为一个类编写代码,然后我在我的程序中使用了你的类。后来,您不喜欢该类的行为方式,因为它的一些实例变量(由我从我的代码中)设置为您没有预料到的值。他们的代码在您的代码中带来了错误。(放心,我不会那样做,别担心。)因为它是一个 Java 程序,所以你应该能够发布一个更新版本的类,我可以在我的程序中替换它而无需更改我自己的任何代码.
上面的场景突出了两个承诺,或者我应该说面向对象 (OO) 的好处:灵活性和可维护性。但这些好处不会自动出现。你必须做点什么。您必须以支持灵活性和可维护性的方式编写类和代码。仅仅因为 Java 支持 OO 概念,它不能为您编写代码。它可以??例如,假设您使用公共实例变量创建类,而其他程序员直接设置实例变量,如以下代码所示:
public class BadExample {
public int size;
public int weight;
...
}
public class AnotherBadExample {
public static void main (String [] args) {
BadExample b = new BadExample ();
b.size = -5; // Legal but bad!!
}
}
现在回到我们在一段之前谈到的场景。BadExample 是您的课程,AnotherBadExample 是我的代码。我已经修改了你的一个变量,它有助于我的代码逻辑,但这完全改变了你的类的工作方式。现在你有麻烦了。你将如何改变你的班级,以至于没有人可以直接改变你的价值观(就像我在我的代码中所做的那样)?您唯一的选择是在您的类中编写一个方法 setSize(int newVal),然后将变量大小的访问修饰符更改为私有。这将确保您在有人试图为您不想要的 size 变量设置值时处理实例,同时确保没有人可以直接访问 size 变量并弄乱您的代码。
但是,不幸的是,这样做,你破坏了我的代码。如果我尝试编译我的 AnotherBadExample 类,我会收到错误,因为 size 变量对我来说不再可见。
我们现在如何解决这种情况?最好的方法是:不要编写任何人都可以修改公共变量的代码。
能够在不破坏所有其他使用您的代码的人的代码的情况下更改您的代码,这是封装的一个关键优势。您应该始终隐藏实现细节。详细地说,您必须始终将您的变量设为私有,然后拥有一组其他人可以用来访问您的变量的公共方法。由于这些方法是公开的,任何人都可以访问它们,但由于它们在您的班级中,您可以确保代码以最适合您的方式运行。因此,在您想要更改代码的情况下,您所要做的就是修改您的方法。没有人受到伤害,因为我只是在我的代码中使用了您的方法名称,而您方法中的代码并没有给我带来太多困扰。
如果你想要可维护性、灵活性和可扩展性(我猜你确实想要),你的设计必须包括封装。你是怎样做的?• 保护实例变量(使用访问修饰符,主要是私有的)。• 创建公共访问器方法,并强制调用代码使用这些方法,而不是直接访问实例变量。• 对于方法,使用set 和get 的JavaBeans 命名约定。
我们将访问方法称为 getter 和 setter,尽管有些人更喜欢更高级的术语 accessors 和 mutators。(就我个人而言,我将使用术语 getter 和 setter)无论您想如何称呼它们,它们都是其他程序员必须通过才能访问您的实例变量的方法。它们看起来很简单,如果您一直在编写 java 代码,您可能一直在使用它们:
public class GoodExample {
// protect the instance variable only an instance of your class can access it
private int size;
// Provide public getters and setters
public int getSize() {
return size;
}
public void setSize(int newSize) {
size = newSize;
}
}
您现在可能在喃喃自语,拥有什么都不做而只是设置或获取值的方法有什么好处。我宁愿有一个公共变量。如果你这样做了,请转到封装下的第一段并重新阅读整个内容。如果你没有这样做,但问我,我们应该在 setSize() 方法中拥有的验证代码在哪里,以确保没有人将其修改为无效值,我的朋友,这只是一个示例类。我让您思考实施需要如何。至少你不会因为像我这样的人和你一起编码或更糟的人而最终受到意想不到的冲击!
封装是信息隐藏。它可以通过java中的访问修饰符 (private、public、protected、default)来实现。因此,通过使用访问修饰符,我们可以对变量和方法的可见性施加限制。
并且封装还将与单个类中的实体相关的函数和变量包装起来。
getter 和 setter 方法用于从外部访问类的实例变量,从而保护对实例变量的直接访问。