SCJP认证 1.5 (3) 声明类成员
2011-02-21 23:52
204 查看
protected和默认访问控制级别几乎完全相同,但有一点主要区别。只有当访问默认成员的类属于同一个包时,才能访问默认成员,而杜宇保护成员来说,即使紫二磊位于不同的包中,该子类也能访问它(通过继承)。请看下面给的两个类:
另一个源文件中有以下内容:
可以看出,第一个文件中的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 访问级别的实例变量(记住,实例变量就是成员)。
上面的代码能够编译。但请注意,Child类是通过继承访问这个protected变量的。一定要记住,只要谈到子类有权访问超类成员时,都是在谈论子类继承成员,而不是通过关超类实例的引用简单地访问该成员 。
下面观察一下,如果子类Child试图使用Parent类引用访问protected变量时会怎么样。
编译器会“高兴地”显示错误!
到现在为止我们已经知道了保护成员对除子类外的所有类实际上都有包级访问或默认访问权限。我们已经看到包外子类能偶继承保护成员。最后,看到包外子类不能使用超类引用访问保护成员。
默认访问细节
让我们从超类成员的默认行为开始。将修改Parent的成员x使它成为默认的。
注意,我们没有在变量x的前面放置访问修饰符。记住,如果没有在类或成员声明的前面键入访问修饰符,则其访问控制是默认的,也就意味着包级访问。现在尝试访问前述Child类中的默认成员。
当编译Child文件时,会出现编译错误
编译器给出错误将成员声明为private时给出的错误相同。子类Child(与超类Parent位于不同的包中)不能看到或者使用默认的超类成员x!现在,对于同一个包中的两个类,默认访问又将怎么样呢?
第二个类中有以下代码:
局部变量 和访问修饰符
访问修饰符可以应用于局部变量吗?绝对不行!
永远不能将访问修饰符应用于局部变量,因此,要特别注意如下形式代码:
可以肯定,用访问修饰符声明的所有局部变量都无法编译通过。事实上,只有一个修饰符能够应用于局部变量,那就是final。
表1.2 列出了所有访问和可见性的组合,应该花写时间将它弄懂。接下来将介绍应用于长远声明的其他(非访问)修饰符。
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 |
相关文章推荐
- SCJP认证 1.5(2) 声明类成员
- SCJP认证范围 1.5 声明类成员
- 黑马程序员——声明类Person,包含2个成员变量:name、age。定义函数sayHello(),调用时输出:我叫***,今年***岁了。声明类Chinese继承Person
- 声明类和结构体时成员顺序将影响其大小
- 声明类person,该类定义了两个数据成员,一个带参的构造方法,一个具有两个参数的构造方法,一个方法prin()
- 6、 声明类Student,包含3个成员变量:name、age、score,
- 黑马程序员---------------------声明类Students,包含3个成员变量:name、age、score,创建5个对象装入TreeSet,按照成绩排序输出结果(考虑成绩相同的问题)。
- 统计实例的个数:通过声明类的静态数据成员方式解决
- 黑马程序员—声明类Person,包含2个成员变量:name、age。定义函数sayHello(), * 调用时输出:我叫***,今年***岁了。声明类Chinese继承Person。
- 在名字空间中声明类和成员函数
- 声明一个哺乳动物类Mammal,再由此派生出狗类Dog,二者都定义Speak()成员函数,基类中定义为虚函数,声明类Dog的一个对象,调用函数Speak()
- C++在命名空间中声明类和成员函数
- “黑马程序员”声明类Student,包含3个成员变量:name、age、score,创建5个对象装入TreeSet,按照成绩排序输出结果(考虑成绩相同的问题)
- 直接调用类成员函数地址
- 直接调用类成员函数地址 (你不知道的事)
- 南通骑龙汽修的成员嘛
- 如何破解海蜘蛛ISP6.1.5 极其isp运营商 v6.1.5
- Java 多线程(三)线程间的通信jdk1.5中Lock,Condition---生产者消费者为例
- ubuntu16.04+tnesorflow1.5+anaconda5+cuda9.0+cudnn7不走弯路安装方法
- 修改asp.net2.0内置成员管理中的强密码规则