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