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

时间:2019-04-29 03:17:57  来源:igfitidea点击:

访问修饰符表示给予或限制对类变量和方法的访问的方式。一个原因是 封装(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;
    }
}