如何在Java中使用Access Modifiers(为什么要使用getter方法?)

时间:2012-03-04 21:07:58

标签: java

我有一个简单而又愚蠢的问题。我们在Java中使用访问修饰符来访问类中的变量。我不明白,如果我们可以使用公共类中定义的属性访问类外的私有类变量,那么public和private之间有什么区别?私人课程外仍可使用。我不明白这个公共私人概念的概念。

5 个答案:

答案 0 :(得分:2)

如果我理解你的问题,你会问为什么有人会写这个:

public class MyClass {
    private int value;
    public int getValue() {
        return value;
    }
    public int setValue(int val) {
        value = val;
    }
}

而不仅仅是:

public class MyClass {
    public int value;
}

主要原因是从客户端代码隐藏MyClass的内部结构。这样做的好处是,您可以更轻松地修改MyClass的内部结构。例如,您可能会在MyClass更改时确定value中的其他字段需要更新。如果value的访问分散在您的代码中的任何地方(如果您的代码充当其他人代码的库,则很难实现),这将很难实现而不会出错。

如有必要,您还可以重写getValue()setValue(int)以同步对值的访问,将记录记录到value或执行任何其他操作。

答案 1 :(得分:1)

私有成员和函数只能在类中访问(还有其他一些技术,比如反射来从类外部访问它们,但是现在让我们忽略它们。)

可以从任何其他类访问公共函数或成员。公共函数可以从其自己的类访问私有成员

通常,公共函数是您希望向外部类公开的内容。它们通常定义类所做的事情,而不是它如何做。例如,如果类A具有名为doS​​omething的公共函数,则类B可以调用该函数。它并不关心A是如何做到的,它只关心它做到了。在内部,doSomething可能会访问一些内部私有变量。因为B不依赖于那些变量,所以这些细节可以在不影响方法调用的情况下改变。

此概念称为encapsulationinformation hiding。一些谷歌搜索这些术语应该提供更详细的例子。

答案 2 :(得分:1)

如果我理解正确,你问的是什么区别:

public class A {
    public int x;
}

public class A {
    private int x;

    public int getX() { return x; }
    public void setX(int x) { this.x = x; }
}

不同之处在于,在第一种情况下,您按原样访问类成员,没有其他逻辑。在第二种情况下,您可能有其他逻辑,因为您正在调用方法。例如:

public class A {
    private int x;

    public int getX() { return x; }
    public void setX(int x) { if(x > 0) this.x = x; }
}  

在这种情况下,如果提供的值大于0,则只为x设置新值。

此概念称为封装。它允许您透明地处理各种特殊条件,而不会将逻辑暴露在类外。

答案 3 :(得分:0)

它被称为encapsulation。您可以将其视为控制对象的内部状态,并仅显示适合调用者的公共接口或契约。

答案 4 :(得分:0)

类变量(或字段)由于多种原因被声明为私有(所有这些都基于名为information hiding的概念)。

一个原因是您可能希望控制对您的字段的访问(例如,过滤某些值)。

例如

public class Person {

    private String name;

    // construtor and getter

    public void setName(String name) {
        if (name == null) {
            throw new IllegalArgumentException("the name of a person may not be null");
        }
        this.name = name;
    }
}

第二个原因是我们可能希望隐藏我们正在使用的类的特定实现。接口List指定用于访问有序元素集合的合同。 ArrayListLinkedListList的两种不同实现。在内部,您可以使用ArrayList作为您的实现,但只希望公开公开您使用列表。这意味着,如果您随后发现LinkedList将是一个更好的实现,那么您将不会破坏任何依赖于您的课程。

考虑B级。

public class B {

    private ArrayList<String> list;

    // constructor

    public List<String> getList() {
        return list;
    }

    public ArrayList<String> getListTheBadWay() {
        return list;
    }

}

我可以像这样轻松使用B级。

B b = new B();
List<String> list1 = b.getList();
ArrayList<String> list2 = b.getListTheBadWay();

如果将B类更改为使用LinkedList,那么使用getListTheBadWay()的行将会中断,而使用getList()的行将继续有效。