您的位置:首页 > 其它

SCJP认证 1.5 (3) 声明类成员

2011-02-21 23:52 204 查看
protected和默认访问控制级别几乎完全相同,但有一点主要区别。只有当访问默认成员的类属于同一个包时,才能访问默认成员,而杜宇保护成员来说,即使紫二磊位于不同的包中,该子类也能访问它(通过继承)。请看下面给的两个类:

package certification;
public class OtherClass {
void testIt(){	//No modifier means method has default access
System.out.println("OtherClass");
}
}


另一个源文件中有以下内容:

package somethingElse;
import certification.OtherClass;
class AccessClass{
public static void main(String[] args){
OtherClass o = new OtherClass();
o.testIt();
}
}


可以看出,第一个文件中的testIt()具有默认访问(也就是包级访问) 。还要注意,OtherClass类与AccessClass类位于不同的包中。AccessClass能够使用testIt()方法吗?它会产生编译错误码?看看编译结果就知道了:

No Method matching testIt() found in class

certification.OtherClass o.testIt();

从前面的结果可以看出,AccessClass类不能使用OtherClass类的方法testIt(),因为testIt()具有默认访问,而AccessClass与OtherClass不在同一个包中。因此,AccessClass不能看到他,编译报错。

只有在讨论子类是,默认和保护行为才有区别。如果protected关键字被用到定义一个成员,则声明该成员的类的任何子类能够通过继承访问它。及时超类和子类位于不同岗顶包中也没有关系,被保护的超类成员对其子类仍然是可见的。

保外子类有权访问超类()父类 成员是什么意思?它意味着子类继承该成员。

然而,这并不意味着保外子类能够使用超类实例的引用访问该成员。换句话说,保护等于继承。保护不是指子类能够处理受保护的超类成员,而是保护它的继承关系。因此,如果包外子类获得超类引用,该子类还是不能在超类引用上使用点运算符来访问受保护的成员。 换句话来说,对包外子类,子类使用对超类的引用时,保护成员就变得如调用私有成员(默认成员)一样。

总的一句,子类只能通过继承看到受保护的的成员。

protected的细节

让我们观察超类的一个具有protected 访问级别的实例变量(记住,实例变量就是成员)。

package certification;
public class Parent {
protected int x = 9;//protected access
}


package certification;
public class Parent {
protected int x = 9;//protected access
}


上面的代码能够编译。但请注意,Child类是通过继承访问这个protected变量的。一定要记住,只要谈到子类有权访问超类成员时,都是在谈论子类继承成员,而不是通过关超类实例的引用简单地访问该成员 。

下面观察一下,如果子类Child试图使用Parent类引用访问protected变量时会怎么样。

package other;
import certification.Parent;
class Child extends Parent{
public void testIt(){
System.out.println("x is " + x);
Parent p = new Parent();
System.out.println("X in parent is " + p.x); // Compiler Error
}
}


编译器会“高兴地”显示错误!


到现在为止我们已经知道了保护成员对除子类外的所有类实际上都有包级访问或默认访问权限。我们已经看到包外子类能偶继承保护成员。最后,看到包外子类不能使用超类引用访问保护成员。

默认访问细节

让我们从超类成员的默认行为开始。将修改Parent的成员x使它成为默认的。

package certification;
public class Parent{
int x=0; // No Access modifier, means default
//(package) access
}


注意,我们没有在变量x的前面放置访问修饰符。记住,如果没有在类或成员声明的前面键入访问修饰符,则其访问控制是默认的,也就意味着包级访问。现在尝试访问前述Child类中的默认成员。

当编译Child文件时,会出现编译错误


编译器给出错误将成员声明为private时给出的错误相同。子类Child(与超类Parent位于不同的包中)不能看到或者使用默认的超类成员x!现在,对于同一个包中的两个类,默认访问又将怎么样呢?

package certification;
public class Parent {
int x=9;//default access
}


第二个类中有以下代码:

package certification;
class Child extends Parent{
public static void main(String[] args){
Child sc = new Child();
sc.testIt();
}
public void testIt(){
System.out.println("Variable x is " + x); //No Problem
}
}


局部变量 和访问修饰符

访问修饰符可以应用于局部变量吗?绝对不行!

永远不能将访问修饰符应用于局部变量,因此,要特别注意如下形式代码:

class Poo {
void doStuff(){
private int x=7; // error
this.doMore(x);
}
}


可以肯定,用访问修饰符声明的所有局部变量都无法编译通过。事实上,只有一个修饰符能够应用于局部变量,那就是final。

表1.2 列出了所有访问和可见性的组合,应该花写时间将它弄懂。接下来将介绍应用于长远声明的其他(非访问)修饰符。

可见性

Public

Protected

Default

Private

从同一个类

YES

YES

YES

YES

从同一个包中的任何类

YES

YES

YES

NO

从同一个包中的子类

YES

YES

YES

NO

从同一个包外的子类

YES

YES,
( By

Inheritance

)

NO

NO

从包外的任何非子类的类

YES

NO

NO

NO

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐