Java方法和属性的访问修饰符


访问修饰符表示给予或限制对类变量和方法的访问的方式。一个原因是 封装(encapsulation)的概念,它声明实例变量不能直接访问,而只能通过访问方法(前缀为get或set)访问。另一个原因是控制如何使用类,以及如何和哪些值进入实例变量(例如,如果实现了具有age实例变量的Person类,则不希望允许其他程序员直接用任何值初始化它,因为它们可以放一个负数)

类成员访问修饰符是:

1
2
3
4
public
protected
default (当我们没有定义访问修饰符时)
private

从简短的描述中可以看出,访问修饰符表示从其他类访问类成员的规则。

对于一个类,尽管有访问修饰符,你仍然可以访问它的方法和变量。

查看或访问类方法或变量是什么意思

如果我们分析一个非静态的实例变量或方法,我们知道使用点(.)运算符引用可以访问其实例变量或调用其方法。但是,因为OOP意味着实现多个类,所以我们可以或者不可以从其他类中实现,即使它们是所分析类的子类。

因此,在Java中,看到类方法或变量意味着能够调用或访问它:

如果我们考虑到 main包中定义的 ClassA

1
2
3
4
5
6
7
8
9
10
11
12
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()

1
2
3
4
5
6
7
8
9
10
11
12
13
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类:

1
2
3
4
5
package main;
public class ClassA{
public int publicAttribute; //public
}

然后,public属性是可见的,或者可以在属于 同一包中的类的方法中访问:

1
2
3
4
5
6
7
8
9
package main; //同一个包
public class ClassB {
public static void doSomething()
{
ClassA ref = new ClassA();
ref.publicAttribute = 20;
}
}

然后,public属性是可见的,或者可以在属于 同一包中的子类的方法中访问:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main; //同一个包
public class SubClassA extends ClassA {
public void doSomething(){
ClassA ref = new ClassA();
//通过引用访问
ref.publicAttribute = 20;
//通过继承访问
this.publicAttribute = 30;
}
}

那么public属性是可见的,或者可以在属于 其他包中的子类的方法中访问:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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的方法中访问:

1
2
3
4
5
6
7
8
9
10
11
package other; //其他包
import main.ClassA;
public class ClassC {
public static void doSomething()
{
ClassA ref = new ClassA();
ref.publicAttribute = 20;
}
}

私有访问修饰符 - Private

Private access修饰符是限制最严格的一个,因为它阻止了从包含类之外的代码对变量或方法的访问。

因此,

对于private,只能从属于同一类的方法访问属性和方法

1
2
3
4
5
6
7
8
9
10
package main;
public class ClassA{
private int privateAttribute; //private
public void doSomething(){
//visible only in the same class
privateAttribute = 20;
}
}

默认访问修饰符 - Default

默认情况下(当我们不编写任何访问修饰符时),访问修饰符介于public和private之间,因为在同一个包之外的代码中阻止了对变量或方法的访问。它类似于类的默认访问修饰符(请参阅),默认属性或方法可从以下位置访问:

同一类;同一包中的其他类;同一包中的子类;

对于类A:

1
2
3
4
5
6
7
8
9
10
11
package main;
public class ClassA{
int defaultAttribute; //default
public void doSomething(){
//同一个类中可见
defaultAttribute = 20;
}
}

defaultAttribute属性在同一包中的其他类中可见:

1
2
3
4
5
6
7
8
package main; //相同包
public class ClassB {
public static void doDomething(){
ClassA ref = new ClassA();
ref.defaultAttribute = 30;
}
}

从同一个包中的子类可见:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main; //相同的包
public class SubClassA extends ClassA {
public void doSomething(){
ClassA ref = new ClassA();
//通过引用访问
ref.defaultAttribute = 20;
//通过继承访问
this.defaultAttribute = 30;
}
}

默认属性和方法在 包外(子类或类)不可见:

1
2
3
4
5
6
7
8
9
10
11
package other; //其他包
import main.ClassA;
public class ClassC {
public static void doSomething(){
ClassA ref = new ClassA();
//不可见
ref.defaultAttribute = 20; //compiler error
}
}

受保护访问修饰符 - Protected

OOP的一个优点是继承性,因为它允许通过扩展而不是修改现有的类来开发新的类。

由于基类(现有类)和子类(扩展基类的新类)之间存在特殊关系,因此可以使用访问修饰符,该修饰符只向子类授予对属性和方法的访问权限。改访问修饰符protected

受保护的属性在以下位置可见:

同一包中的类:

1
2
3
4
5
6
7
8
9
10
11
package main;
public class ClassA{
protected int protectedAttribute; //protected
public void doSomething(){
//在同一个类中访问
protectedAttribute = 20;
}
}

同一包中的子类(通过继承和引用)

1
2
3
4
5
6
7
8
package main; //同一个包
public class ClassB {
public static void doSomething(){
ClassA ref = new ClassA();
ref.protectedAttribute = 40;
}
}

其他包中的子类( **重要!只有通过继承]:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
package main; //同一个包
public class SubClassA extends ClassA {
public void doSomething(){
ClassA ref = new ClassA();
//通过引用访问
ref.defaultAttribute = 20;
//通过继承访问
this.defaultAttribute = 30;
}
}

受保护的属性在包外部的类中不可见:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
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;
}
}


原文链接:https://codingdict.com/