关于类:通过getter和setter(访问器)函数访问私有变量的意义何在?

Whats the point of accessing private variables through getter and setter (accessor) functions?

在类中,变量通常是私有的,用于封装,并且将变量限制在某个范围内,这样可以更好地控制错误并减少错误。这是有意义的,因为访问变量的位置越少,使用该变量发生错误的位置就越少。

但是,我总是看到变量变为私有的,然后看到一个用于检索该值的getter和setter函数(有时甚至是指向该变量的指针!)例如,int a是私有的,以防止公共访问,但getA()setA()允许直接访问它们。

那么getter函数和setter函数是否会挑战私有化这一点呢?我的意思是带有访问函数的私有变量与公共变量相同,只有访问它们的代码发生了变化。(object.variable与object.getvariable())

人们使用访问函数将变量设置为私有有什么原因吗?与公开相比有什么好处吗?

我一般说的是编程,但大部分是C语言(即C、C++、C、Obj-C)。


这里的关键词和标签是"封装"。你隐藏了a的细节,但仍然可以使用它。我喜欢已经列出的原因,还有很多。这是另一个,您正在调试,您发现a的值不正确。如果a是公共的,您必须检查每个访问a的地方。如果a使用setter方法是私有的,那么您知道a唯一可以更改的地方是调用setA()—是放置断点的好地方;)


也许您想在库的下一个版本中添加一些检查(或者在有人读取值时执行某些操作),如果变量在当前版本中是公共的,升级库版本将花费大量的工作。


因为如果您更改了该变量的内部表示,或者希望在设置或检索该变量时做得更多,那么它不会破坏所有使用它的其他类(如果它是库,则不必更改API)。

它还意味着您可以轻松地设置一个断点,以查看何时使用它(尽管大多数语言/调试器都有某种类型的数据断点)。


当我开始学习面向对象编程时,我也有同样的问题,因为在大多数书籍中,它们只是将变量设为私有,并添加公共方法(getter/setter)来访问它们,所以我在想,如果我可以通过公共方法访问该变量,那么将该变量设为私有又有什么意义呢?

当我开始实现实际的业务应用程序时,我得到了答案。

让我们考虑一个班上的学生,包括学生的名字、学号、三门科目的分数。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
Class Student {

   private  int rollno;
    private int java_marks;
    private int cpp_marks;
    private int unix_marks;
    private int percentage;


    public int getJava_marks() {
        return java_marks;
    }
    public void setJava_marks(int java_marks) {
        if (java_marks > 100) {
            System.out.println("Marks value should be less than 100");
            //throw exception
        }
        this.java_marks = java_marks;
    }
    public int getCpp_marks() {
        return cpp_marks;
    }
    public void setCpp_marks(int cpp_marks) {
        if (cpp_marks > 100) {
            System.out.println("Marks value should be less than 100");
            //throw exception
        }
        this.cpp_marks = cpp_marks;
    }
    public int getUnix_marks() {

        return unix_marks;
    }
    public void setUnix_marks(int unix_marks) {
        if (unix_marks > 100) {
            System.out.println("Marks value should be less than 100");
            //throw exception
        }
        this.unix_marks = unix_marks;
    }
    public int getPercentage() {
        this.percentage = (this.cpp_marks + this.unix_marks + this.java_marks) /3;
        return percentage;
    }

    public int getRollno() {
        return rollno;
    }
    public void setRollno(int rollno) {
        this.rollno = rollno;
    }

}

这里之所以要做私有变量是因为两个原因

  • 验证:如果用户为标记提供了无效值,那么学生对象不应使用无效数据创建,并抛出适当的错误/异常。在标记为公共变量的情况下,用户可以为它们设置任何值,因此我添加了验证/安全性,以确保创建的严重学生对象具有正确的数据。

  • 安全在百分比的情况下,用户不能设置自己的百分比。百分比是在内部计算和设置的。这里我不提供百分比的setter方法,所以用户只能通过getter方法获取/读取百分比值。

  • 这将导致抽象中的安全性,即对类变量的访问是有限的(只读)。


    为什么需要封装?为什么需要OOP?C编程语言是否能够完成我们今天所做的工作?把这件事告诉你的朋友。或者如果你曾在拥有数百万行代码的大型系统上工作过。您所使用的是一个关键数据结构的公共变量,可以从程序的每个模块访问它。


    类定义了行为,而成员是对象的状态……因此拥有setter和getter定义了类的封装行为,让其他人查找/更改对象状态。

    换言之,不同之处在于让你的邻居进入你的房子,拿走他想要的东西(把课堂上所有的东西都公之于众),或者确保邻居来问我他想要什么,我给他(有一个getter/setter…)