Java方法和属性的访问修饰符
访问修饰符表示给予或限制对类变量和方法的访问的方式。一个原因是 封装(encapsulation)的概念,它声明实例变量不能直接访问,而只能通过访问方法(前缀为get或set)访问。另一个原因是控制如何使用类,以及如何和哪些值进入实例变量(例如,如果实现了具有age实例变量的Person类,则不希望允许其他程序员直接用任何值初始化它,因为它们可以放一个负数)
类成员访问修饰符是:
public protected default (当我们没有定义访问修饰符时) private
从简短的描述中可以看出,访问修饰符表示从其他类访问类成员的规则。
对于一个类,尽管有访问修饰符,你仍然可以访问它的方法和变量。
查看或访问类方法或变量是什么意思
如果我们分析一个非静态的实例变量或方法,我们知道使用点(.)运算符和引用可以访问其实例变量或调用其方法。但是,因为OOP意味着实现多个类,所以我们可以或者不可以从其他类中实现,即使它们是所分析类的子类。
因此,在Java中,看到类方法或变量意味着能够调用或访问它:
如果我们考虑到 main包中定义的 ClassA:
package main;
public class ClassA{
private int privateAttribute; //private
public int publicAttribute; //public
//class method
void doSomething(){
privateAttribute = 10; //accessible
publicAttribute = 20; //accessible
}
}
以及在同一个包中定义的类 Main,该类具有静态方法 Main():
package main;
public class Main {
public static void main(String[] args) {
ClassA ref = new ClassA();
//public attributes are visible
ref.publicAttribute = 10;
//private attributes are NOT visible
//compiler error: privateAttribute has private access in...
ref.privateAttribute = 20; //compiler error
}
}
在前面的例子中,我们不能访问 ClassA对象的 privateAttribute,因为它是私有的,并且只能通过类 ClassA的方法访问。可以说, privateAttribute在类 Main中不可见。这种情况是由Java编译器控制的,它会生成一个编译器错误,消息为atributPrivat has private access in…。private属性只能从类 ClassA的方法访问。
相反,public属性 publiccattribute是可访问的。它在 Main类上可见。
在前面的属性示例中,同样的规则也适用于方法。
公共访问修饰符 Public
公共访问修饰符的限制最小,因为它使变量或方法在任何其他类(子类或非子类)和任何包中都可见。
如果我们考虑包 main中定义的 ClassA类:
package main;
public class ClassA{
public int publicAttribute; //public
}
然后,public属性是可见的,或者可以在属于 同一包中的类的方法中访问:
package main; //同一个包
public class ClassB {
public static void doSomething()
{
ClassA ref = new ClassA();
ref.publicAttribute = 20;
}
}
然后,public属性是可见的,或者可以在属于 同一包中的子类的方法中访问:
package main; //同一个包
public class SubClassA extends ClassA {
public void doSomething(){
ClassA ref = new ClassA();
//通过引用访问
ref.publicAttribute = 20;
//通过继承访问
this.publicAttribute = 30;
}
}
那么public属性是可见的,或者可以在属于 其他包中的子类的方法中访问:
package other; //其他包
import main.ClassA;
public class OtherSubClassA extends ClassA {
public void doSomething(){
ClassA ref = new ClassA();
//通过引用访问
ref.publicAttribute = 20;
//通过继承访问
this.publicAttribute = 30;
}
}
然后,public属性是可见的,或者可以在属于 classes inother package的方法中访问:
package other; //其他包
import main.ClassA;
public class ClassC {
public static void doSomething()
{
ClassA ref = new ClassA();
ref.publicAttribute = 20;
}
}
私有访问修饰符 - Private
Private access修饰符是限制最严格的一个,因为它阻止了从包含类之外的代码对变量或方法的访问。
因此,
对于private,只能从属于同一类的方法访问属性和方法
package main;
public class ClassA{
private int privateAttribute; //private
public void doSomething(){
//visible only in the same class
privateAttribute = 20;
}
}
默认访问修饰符 - Default
默认情况下(当我们不编写任何访问修饰符时),访问修饰符介于public和private之间,因为在同一个包之外的代码中阻止了对变量或方法的访问。它类似于类的默认访问修饰符(请参阅),默认属性或方法可从以下位置访问:
同一类;同一包中的其他类;同一包中的子类;
对于类A:
package main;
public class ClassA{
int defaultAttribute; //default
public void doSomething(){
//同一个类中可见
defaultAttribute = 20;
}
}
defaultAttribute属性在同一包中的其他类中可见:
package main; //相同包
public class ClassB {
public static void doDomething(){
ClassA ref = new ClassA();
ref.defaultAttribute = 30;
}
}
从同一个包中的子类可见:
package main; //相同的包
public class SubClassA extends ClassA {
public void doSomething(){
ClassA ref = new ClassA();
//通过引用访问
ref.defaultAttribute = 20;
//通过继承访问
this.defaultAttribute = 30;
}
}
默认属性和方法在 包外(子类或类)不可见:
package other; //其他包
import main.ClassA;
public class ClassC {
public static void doSomething(){
ClassA ref = new ClassA();
//不可见
ref.defaultAttribute = 20; //compiler error
}
}
受保护访问修饰符 - Protected
OOP的一个优点是继承性,因为它允许通过扩展而不是修改现有的类来开发新的类。
由于基类(现有类)和子类(扩展基类的新类)之间存在特殊关系,因此可以使用访问修饰符,该修饰符只向子类授予对属性和方法的访问权限。改访问修饰符protected。
受保护的属性在以下位置可见:
同一包中的类:
package main;
public class ClassA{
protected int protectedAttribute; //protected
public void doSomething(){
//在同一个类中访问
protectedAttribute = 20;
}
}
同一包中的子类(通过继承和引用)
package main; //同一个包
public class ClassB {
public static void doSomething(){
ClassA ref = new ClassA();
ref.protectedAttribute = 40;
}
}
其他包中的子类( **重要!只有通过继承]:
package main; //同一个包
public class SubClassA extends ClassA {
public void doSomething(){
ClassA ref = new ClassA();
//通过引用访问
ref.defaultAttribute = 20;
//通过继承访问
this.defaultAttribute = 30;
}
}
受保护的属性在包外部的类中不可见:
package other; //其他包
import main.ClassA;
public class OtherSubClassA extends ClassA {
public void doSomething(){
ClassA ref = new ClassA();
//不可以通过引用访问
ref.protectedAttribute = 20; //compiler error
//通过继承访问
this.protectedAttribute = 30;
}
}

