成员的访问权限
首先先声明一下friendly默认访问权限,就是在类的成员变量或者成员方法在没有被public,private,protected修饰时就是默认访问权限。(唉,说到这里就想起来java期末考试时老师让建一个“友好型”的方法,我在声明方法的时候想不出friendly怎么拼写,最后那里空了一格没写,现在回想起来真是被机智的自己感动哭了。)
另外,需要注意一下局部变量不能用修饰符修饰,它们只能在方法内使用。
以下是几个访问权限控制修饰词的访问范围:
本类访问 包内访问 包外子类访问 包外非子类访问
Public Y Y Y Y
Friendly Y Y N N
Protected Y Y Y N
Private Y N N N
Public 修饰的变量和方法是没有限制包内外都可以访问。
Friendly (就这样写好了,它是默认的,但我总得叫它点儿什么)修饰的变量和方法是有包访问权限,本包可以访问,外包不可访。
Protected 修饰的变量和方法也是有包访问权限,它与friendly的
区别是,它所在类的包外子类可以继承和访问protected 修饰的变量和方法。
Private 除了包含该成员的类其他任何类都无法访问该成员。
类的访问权限
类的访问权限仅有两个选择:包访问权限(默认)和public。如果不希望对该类拥有访问权限,可以把所有的构造器都指定为private,从而阻止任何人创建该类的对象,但是在该类的static成员内部可以创建。
验证代码如下所示:
包内测试:
package cn.zjnu.edu.java2425;
class Soup1{
private Soup1(){System.out.println("用static方法创建Soup1对象并返回引用");}
public static Soup1 makeSoup(){
return new Soup1();
}
}
class Soup2{
private Soup2(){System.out.println("通过static private成员创建Soup2对象,通过access()方法访问");}
private static Soup2 ps1=new Soup2();
public static Soup2 access(){
return ps1;
}
}
class Soup3{
Soup3(){
System.out.println("包内可以访问默认类,包外不能访问");
}
}
public class Lunch {
void testPrivate(){
//Soup1 soup=new Soup1();不能这样的,报错信息“The constructor Soup1() is not visible”
}
void testStatic(){
Soup1 soup=Soup1.makeSoup();
}
void tastSingleton(){
Soup2.access();
}
public Lunch(){//这里构造器也要是public才能进行包外访问
System.out.println("包内外都可以访问public类");
}
public static void main(String arg[]){
Lunch l1=new Lunch();
l1.testStatic();
l1.tastSingleton();
Soup3 s=new Soup3();
}
}
运行结果:
包内外都可以访问public类
用static方法创建Soup1对象并返回引用
通过static private成员创建Soup2对象,通过access()方法访问
包内可以访问默认类,包外不能访问
包外测试:
package cn.zjnu.practise;
import cn.zjnu.edu.java2425.Lunch;
public class TestClass {
public static void main(String[] args) {
Lunch l=new Lunch();
//Soup3 s3=new Soup3();报错,包外不能访问Soup3
}
}
运行结果:
包内外都可以访问public类
在代码中
public static Soup1 makeSoup(){
return new Soup1();
}
Soup1中创建一个static方法,它创建一个新的Soup1对象并返回一个对它的引用。
Soup2类的对象是作为Soup2的一个static private成员而创建的,所以有且仅有一个,并且除非是通过public方法access(),否则是无法访问到它的。
对于public类:
- 每个编译单元都只有一个public类,有一个以上的public类,编译器会报错。
- Public类的名称必须与含有该编译单元的文件名相匹配,包括大小写。
- 编译单元内完全不带public类也是可能的,在这种情况下可以随意对文件命名。
类访问权限+成员访问权限:(取两者最小访问权限)
Public类的成员:
本类访问 包内访问 包外子类访问 包外非子类访问
Public Y Y Y Y
Friendly Y Y N N
Protected Y Y Y N
Private Y N N N
默认类的成员:
本类访问 包内访问 包外子类访问 包外非子类访问
Public Y Y N N
Friendly Y Y N N
Protected Y Y N N
Private Y N N N
验证代码如下所示:
1、创建一个默认类和一个public类
package cn.zjnu.edu.java2425;
class Sub{
Sub(){
System.out.println("默认类:");
}
public void PublicTest(){
System.out.println("public方法可以跨包访问");
}
protected void ProtectedTest(){
System.out.println("protected方法可以被包内其他类访问,可以被包外子类访问");
}
void FriendlyTest(){
System.out.println("默认方法只能包内访问");
}
private void PrivateTest(){
System.out.println("默认类独享的private方法");
}
}
public class Sub1 {
public Sub1(){
System.out.println("public类:");
}
public void PublicTest(){
System.out.println("public方法可以跨包访问");
}
protected void ProtectedTest(){
System.out.println("protected方法可以被包内其他类访问,可以被包外子类访问");
}
void FriendlyTest(){
System.out.println("默认方法只能包内访问");
}
private void PrivateTest(){
System.out.println("本类独享的private方法");
}
public static void main(String[] args) {
System.out.println("类内部private方法测试:");
Sub1 s1=new Sub1();
s1.PrivateTest();
Sub s=new Sub();
//s.PrivateTest();private类不能被其他任何类访问
}
}
运行结果:
类内部private方法测试:
public类:
本类独享的private方法
默认类:
2、包内测试:
package cn.zjnu.edu.java2425;
public class Son {
public static void main(String[] args) {
System.out.println("包内测试:");
Sub1 s1=new Sub1();
s1.PublicTest();
s1.ProtectedTest();
s1.FriendlyTest();
//s1.PrivateTest();private类不能被其他任何类访问
Sub s=new Sub();
s.PublicTest();
s.ProtectedTest();
s.FriendlyTest();
//s.PrivateTest();private类不能被其他任何类访问
}
}
运行结果:
包内测试:
public类:
public方法可以跨包访问
protected方法可以被包内其他类访问,可以被包外子类访问
默认方法只能包内访问
默认类:
public方法可以跨包访问
protected方法可以被包内其他类访问,可以被包外子类访问
默认方法只能包内访问
3、包外其他类测试:
package cn.zjnu.edu.javase;
import cn.zjnu.edu.java2425.Sub1;
public class Son1 {
public static void main(String[] args) {
System.out.println("包外其他类测试:");
Sub1 s1=new Sub1();
s1.PublicTest();
//s1.ProtectedTest();包外其他类protected方法不能被访问
//s1.FriendlyTest();包外其他类friendly方法不能被访问
//s1.PrivateTest();private类不能被其他任何类访问
//Sub s=new Sub();包外默认类不能被访问
}
}
运行结果:
包外其他类测试:
public类:
public方法可以跨包访问
4、包外子类测试:
package cn.zjnu.edu.javase;
import cn.zjnu.edu.java2425.Sub1;
public class Son2 extends Sub1{//包外子类测试
public static void main(String[] args) {
System.out.println("包外子类测试:");
Son2 son=new Son2();
son.PublicTest();
son.ProtectedTest();//包外父类protected方法能被包外子类访问
//son.FriendlyTest();包外父类friendly方法不能被包外子类访问
//s1.PrivateTest();private类不能被其他任何类访问
}
}
运行结果:
包外子类测试:
public类:
public方法可以跨包访问
protected方法可以被包内其他类访问,可以被包外子类访问