通过getter和setter(访问器)函数访问私有变量的重点是什么?

时间:2012-01-24 23:32:58

标签: class oop object encapsulation

在类中,变量通常被私有化以进行封装,并且将变量限制到某个范围允许更好的错误控制和更少的错误。这是有道理的,因为可以访问变量的位置越少,该变量发生错误的位置就越少。

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

那么,getter函数和setter函数是否违背了它的私有性?我的意思是具有访问器功能的私有变量与公共变量相同,只有访问它们的代码才会发生变化。 (object.variable vs object.getVariable())

是否有人使用访问者函数将变量设为私有?与公开相比有什么优势吗?

我说的是一般的编程,但主要是C语言(即C,C ++,C#,Obj-C)。

6 个答案:

答案 0 :(得分:12)

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

答案 1 :(得分:2)

因为如果您更改了该变量的内部表示,或者想要在设置或检索时执行更多操作,则不会破坏使用它的所有其他类(如果它是库,则不必更改你的API)。

这也意味着您可以轻松设置断点以查看它何时被使用(尽管大多数语言/调试器都有某种数据断点)。

答案 2 :(得分:2)

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

答案 3 :(得分:1)

当我开始学习面向对象编程时,我有同样的问题,因为在大多数书中他们只是变量私有并添加公共方法(Getter / Setters)来访问它们所以我在想是否可以访问它通过公开的方法变量,然后指出使变量变为私有。

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

让我们考虑一个班级学生,其中包含学生姓名,滚动号码,3个科目的标记

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;
    }

} 

由于2个原因,这里制作私有变量

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

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

  3. 这导致抽象的安全性,这种安全性仅限于(只读)访问类变量。

答案 4 :(得分:0)

类定义行为,成员是对象的状态......所以有一个setter和getter定义了让别人查找/更改对象状态的类的封装行为。

换句话说,区别就是让你的邻居进入你的房子并拿走他想要的东西(让所有对象在公共场合公开)......或者确保邻居问我想要什么,我给他(有一个吸气剂/安装者......)

答案 5 :(得分:0)

为什么需要封装?为什么需要oop?没有C编程语言能够做我们今天所做的事情吗?向yourslef询问这个问题。或者,如果您已经处理了拥有数百万行代码的庞大系统。您使用的只是可从程序的每个模块访问的关键数据结构的公共变量。