范围
外观
< Java 编程
导航 类和对象 主题: ) |
类的范围,变量或方法的范围是其可见性和可访问性。可见性或可访问性意味着您可以从给定位置使用该项目。
方法参数在整个方法内可见,但在方法外部不可见。
代码清单 3.14:Scope.java
public class Scope {
public void method1(int i) {
i = i++;
method2();
int j = i * 2;
}
public void method2() {
int k = 20;
}
public static void main(String[] args) {
method1(10);
}
}
|
在 代码清单 3.14 中,i
在整个 method1
方法内可见,但在 method2
和 main
方法中不可见。
局部变量在其声明后可见,直到创建局部变量的块结束。
代码部分 3.50:局部变量。
{
...
// myNumber is NOT visible
{
// myNumber is NOT visible
int myNumber;
// myNumber is visible
{
...
// myNumber is visible
}
// myNumber is visible
}
// myNumber is NOT visible
...
}
|
您肯定已经注意到,在本手册中使用的类的方法声明开始处的 public
、protected
和 private
等词。这些关键字在 Java 语言语法中称为 访问修饰符,它们定义了给定项目的范围。
- 如果一个类具有 public 可见性,则该类可以被程序中的任何地方引用。
- 如果一个类具有 protected 可见性,则该类只能在定义该类的包中被引用。
- 如果一个类具有 private 可见性(只有当该类定义为嵌套在另一个类中时才可能发生),则该类只能在外部类中被访问。
- 如果一个变量定义在 public 类中,并且它具有 public 可见性,则该变量可以通过其定义的类在应用程序中的任何地方被引用。
- 如果一个变量具有 protected 可见性,则该变量只能在子类和同一个包中通过其定义的类被引用。
- 如果一个变量具有 package 可见性,则该变量只能在同一个包中通过其定义的类被引用。
- 如果一个变量具有 private 可见性,则该变量只能在其定义的类中被访问。
- 如果一个方法定义在 public 类中,并且它具有 public 可见性,则该方法可以通过其定义的类在应用程序中的任何地方被调用。
- 如果一个方法具有 protected 可见性,则该方法只能在子类和同一个包中通过其定义的类被调用。
- 如果一个方法具有 package 可见性,则该方法只能在同一个包中通过其定义的类被调用。
- 如果一个方法具有 private 可见性,则该方法只能在其定义的类中被调用。
接口方法和接口始终是 public
。您无需指定访问修饰符。它将默认设置为 public
。为了清晰起见,建议使用 public
关键字。
同样,在接口中定义的所有成员变量在类中继承后,默认将变为 static
final
。
类 | 嵌套类 | 方法或成员变量 | 接口 | 接口方法签名 | |
---|---|---|---|---|---|
public
|
从任何地方可见 | 与其类相同 | 与其类相同 | 从任何地方可见 | 从任何地方可见 |
protected
|
N/A | 其类及其子类 | 其类及其子类,以及其包 | N/A | N/A |
package | 仅从其包可见 | 仅从其包可见 | 仅从其包可见 | N/A | N/A |
private
|
N/A | 仅从其类可见 | 仅从其类可见 | N/A | N/A |
粗体表示默认情况。
可见性的一般准则是只使成员具有必要的可见性。如果成员只需要私有,不要将其设置为公有。
这样做,您可以重写类并更改所有私有成员而不会出现编译错误,即使您不知道所有将使用您的类的类,只要您不更改公有成员的签名。
通常,最好将数据设置为私有或受保护的。对数据的访问由setter和getter方法控制。这使程序员能够控制对数据的访问,允许他们检查和处理无效数据。
代码段 3.51:封装。
private String name;
/**
* This is a getter method because it accesses data from the object.
*/
public String getName() {
return name;
}
/**
* This is a setter method because it changes data in the object.
*/
public boolean setName(String newName) {
if (newName == null) {
return false;
} else {
name = newName;
return true;
}
}
|
在代码段 3.51中,setName()
方法仅当新名称不为空时才会更改name
的值。因为setName()
有条件地更改了名称,所以最好返回一个布尔值,让程序知道更改是否成功。
测试您的知识
问题 3.15:考虑以下类。
问题 3.15:Question15.java
public class Question15 {
public static final int QKQKQKQK_MULTIPLIER = 2;
public int ijijijijijijijijijAwfulName = 20;
private int unununununununununCrummyName = 10;
private void mememememememeUglyName(int i) {
i = i++;
tltltltltltltltltlBadName();
int j = i * QKQKQKQK_MULTIPLIER;
}
public void tltltltltltltltltlBadName() {
int k = ijijijijijijijijijAwfulName;
}
public static void main(String[] args) {
mememememememeUglyName(unununununununununCrummyName);
}
}
|
列出此类的字段和方法,这些字段和方法可以在不更改甚至不知道客户端类的情况下重命名。
答案
unununununununununCrummyName
mememememememeUglyName()
每个公有字段或方法都可以被客户端类直接调用,因此如果字段或方法有新名称,此类将返回编译错误。