Java访问修饰符
Java访问修饰符指定哪些类可以访问给定的类及其字段,构造方法和方法。访问修饰符可以为类、构造方法、字段、方法单独指定。 Java访问修饰符有时也被称为Java访问说明符,但正确的名称是Java访问修饰符。类,字段,构造方法和方法可以具有四种Java访问修饰符之一:
- private
- default(package)
- protected
- public
以上每个访问修饰符都会在下面小节中介绍。
为类,构造方法,字段或方法指定访问修饰符有时也称为给类,构造方法,字段或方法作“标记”。例如,指定方法为public也叫做将该方法标记为公共的。
private访问修饰符
如果某个方法或变量被标记为private(将private访问修饰符分配给它),则只有同一个类中的代码才能访问该变量或调用该方法。子类中的代码不能访问变量或方法,也不能从任何外部类进行编码。
类不能用private访问修饰符标记。使用private访问修饰符标记一个类将意味着其他类都不能访问它,也意味着你根本无法真正使用该类。因此private访问修饰符不允许用于类。
以下是将private访问修饰符分配给一个字段的示例:
public class Clock {
private long time = 0;
}
成员变量time被标记为private。这意味着,Clock类中的成员变量time不能从Clock类以外的代码访问。
通过访问器方法访问private字段
当我们需要对从外部访问类的字段进行控制时,通常会将该字段标记为private。在某些情况下,这些字段确实是私有的,也就是说它只能在类内部访问到;但在另外一些情况,我们可以通过访问器方法(getter和setter方法)来获取私有字段。示例如下:
public class Clock {
private long time = 0;
public long getTime() {
return this.time;
}
public void setTime(long theTime) {
this.time = theTime;
}
}
在上面的例子中,两个方法getTime()和setTime()可以访问time成员变量。这两种方法是public(公开的),这意味着它们可以从应用程序任何地方的代码中调用。Java访问修饰符public将在本文稍后介绍。
private构造方法
如果类中的构造方法被分配了private访问修饰符,那就意味着构造方法不能从类之外的任何地方调用。私有构造方法仍然可以从其他构造方法或同一类中的静态方法调用。示例如下:
public class Clock {
private long time = 0;
private Clock(long time) {
this.time = time;
}
public Clock(long time, long timeOffset) {
this(time);
this.time += timeOffset;
}
public static Clock newClock() {
return new Clock(System.currentTimeMillis());
}
}
Clock类的这个版本包含一个private构造方法和一个public构造方法。private构造方法在public构造方法中通过 this()语句调用。同样也在静态方法中通过 new Clock()语句调用。
上面的例子只是向你展示一个私有构造方法可以在公共构造方法和同一个类中的静态方法调用。不要将上述方式视为一个巧妙设计的例子。
default(包)访问修饰符
默认的Java访问修饰符是通过不写任何访问修饰符来声明的。默认的访问修饰符意味着类内部的代码以及与这个类在同一个包中的类内部的代码可以访问该类,字段,构造方法或者方法。因此,默认访问修饰符有时也被称为包访问修饰符。
如果超类中的方法和成员变量(字段)被这些方法和字段标记了默认的访问修饰符,除非子类与超类位于同一个包中,否则子类不能访问它们。
下面是一个默认的包访问修饰符的例子:
public class Clock {
long time = 0;
}
public class ClockReader {
Clock clock = new Clock();
public long readClock{
return clock.time;
}
}
Clock类中的time字段没有访问修饰符,这意味着它被隐含地分配了默认的包访问修饰符。因此,ClockReader类可以读取Clock对象的time成员变量,前提是ClockReader和Clock位于同一个Java包中。
protected访问修饰符
protected(受保护的)访问修饰符提供与默认访问修饰符相同的访问权限,另外即使子类与超类不在同一个包中,子类也可以访问超类的受保护方法和成员变量(字段)。
示例如下:
public class Clock {
protected long time = 0;
}
public class SmartClock() extends Clock{
public long getTimeInSeconds() {
return this.time / 1000;
}
}
在上面的例子中,子类SmartClock有一个名为getTimeInSeconds()的方法,它访问超类Clock的time变量。即使Clock和SmartClock不在同一个包中,这也是完全可以的的,因为time字段被标记了受保护的Java访问修饰符。
public访问修饰符
public访问修饰符表示不管访问代码所处位置,都可以访问该类、字段、构造方法或方法。也就是说访问的代码可以在不同的类和不同的包中。
示例如下:
public class Clock {
public long time = 0;
}
public class ClockReader {
Clock clock = new Clock();
public long readClock{
return clock.time;
}
}
Clock类中的time字段用public访问修饰符标记。因此,ClockReader类所在包位置,都可以访问该time字段。
类访问修饰符
请注意,分配给Java类的Java访问修饰符优先于分配给该类的字段、构造方法和方法的任何访问修饰符。如果该类标记了默认的访问修饰符,那么与该类不同Java包的任何其他类都不能访问该类,包括其构造方法,字段和方法。即使你将那些字段声明为public,甚至是public static也是不行的。
Java访问修饰符private和protected不能分配给一个类。只适用于类中的构造方法,方法和字段。类只能为其分配默认(包)和public访问修饰符。
接口访问修饰符
Java接口旨在指定在实现接口的类中公开可用的字段和方法。因此,你不能在接口中使用private和protected访问修饰符。如果省略访问修饰符,则接口中的字段和方法将隐式声明为public,因此你也不能使用默认访问修饰符(无访问修饰符)。
访问修饰符与继承
在创建某个类的子类时,子类中方法的访问修饰符不能比在超类中的有更少的可访问权限。例如,如果超类中的方法是公共的,那么它也必须在子类中公开,以防子类覆盖方法。如果超类中的方法受保护,那么它必须在子类中是被保护或公开的。
虽然不允许减少重写方法的可访问性,但是允许扩展重写方法的可访问性。例如,如果一个方法被分配了超类中的默认访问修饰符,则允许在子类中指定重写的方法的访问修饰符为public。
下一篇: 继承