内部类访问权限

本文深入探讨Java内部类的访问权限控制,包括private、protected、default和public修饰符的作用范围,以及如何通过接口和多态调用内部类。通过具体代码示例,解释了编译器如何根据引用寻找类并检查访问权限。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这个问题是我学习think in java思考,页面为第四版196面,Exeicise11

首先,我们先来回顾一下,修饰符权限得问题

如图:基础知识就不废话
java权限修饰符

首先我们先来思考以下问题:

1、创建一个private内部类,让他实现一个public接口,写一个方法,尝试指向此private内部类得实例引用,并将此引用想上转型成接口,通过尝试向下转型,说明此内部类被完全隐藏了~

2、将上面问题改成protected呢。创建一个protected内部类…

3、defult

4、public

一、首先我们来看第一个问题
代码如下:

package innerClass;

/*public class Exercise11 {
	public static void main(String[] args) {
	} 
}
*/
interface Ex11Interface {
	void say(String s); 
}


class Friend{
	private String name = "mao";
	public void printName() {
		System.out.println(name);
	}
}

public class Test {
	
	private Friend f = new Friend();
	
	Friend getFriend() {
		return f;
	}
	private class Inner implements Ex11Interface {
		
		public void say(String s) {
			System.out.println(s); 
		}

		/*@Override
		public void what() {
			// TODO Auto-generated method stub
			
		}*/
	}
	
	/*interface Ex11Interface {
		void say(String s);
		void what();
	}*/
	
	Ex11Interface f() {
		return new Inner();
	}
	
	Inner g() {
		return new Inner();
	}
	
	Ex11Interface f2() {
		return new Inner2();
	}
	
	
	protected class Inner2 implements Ex11Interface {
		public void say(String s) {
			System.out.println(s); 
		}

		/*@Override
		public void what() {
			// TODO Auto-generated method stub
			
		}*/
	}
	
	public static void main(String[] args) {
		
	}
	
}
class Ex11 {	
	public static void main(String[] args) {
		Test t = new Test();
		t.f().say("hi"); 
		
		t.f2().say("how are you");
		((Test.Inner2)t.f2()).say("2"); //protected 类可以向下转型
		
		
		
		//t.g().say("hello "); he type Test.Inner is not visible
		System.out.println(t.g()); //但是可以返回他的引用
		
		
		// Error: cannot find symbol: class Inner:
		//((Test.Inner)t.f()).say("hello"); //private 内部类不能向下转型
		
		//测试private对象域
		t.getFriend().printName();
		
		
	} 
}

编译结果:
	hi
    how are you
    2
    innerClass.Test$Inner@33909752
    mao

1

很明显,上面能返回内部类的引用,但是不能访问内部类的属性,否者提示,找不到该类。

首先我们获得到两个信息:1、类中返回的其实都是引用。即使是类中组合情况,将其他类的对象返回,却能访问该引用指向的对象(代码中的Friend就是我测试的例子),为什么呢?.

很明显编译器的工作方式是这样,(此过程没有解析jvm,只是个人对访问权限控制的设想),通过对象引用访问值,如果是基本类型,那不存在什么访问权限啥的,直接输出值,如果对象引用指向的是对象的话,那编译器会通过你的对象引用,访问指向的类.

然后这时候,你前面看得类的权限修饰符起作用了,private的很明显禁止任何外部访问,直接相当于屏蔽了,所以编译器提示找不到该类,而private Friend对象能访问,是因为编译器看得是Friend类!,是defult,所以同包肯定能访问,如果你在另一个包继承了Test就不行了

2

加入是protected修饰的内部类呢,Test.java代码上面有,这里贴上Ex11.java代码
两个java文件是不同包的,因为这样才能隔离protected包含的同包访问权限,问题暴露得更多

代码如下:

package innerClass.Exercise6;
import innerClass.Test;

public class Ex11 {
	
	public static void main(String[] args) {
		
		//The type Test.Inner is not visible
		//Test.Inner;
		//Test2.Inner2 ti;
		
	}
	
	class Test2 extends Test{
		Test.Inner2 i ; //protected修饰得内部类还是可以在子类中调用
		
		
		//private 修饰ide内部类继续隐藏
		//Test.Inner;
	}
}

很明显,main里面得 Test.inner和Test.inner2都显示不了,Test.inner是private内部类,完全屏蔽,访问不了很正常,那么Test.inner2是protected,因为是不同包,所以继承得protected显然,不能在此包使用了,只能在继承了Test得Test2类得内部使用。

总结:

内部类得访问权限,也是根据访问修饰符来控制得,但是要调出逻辑误区,即Java中返回得全是引用,java’编译器根据引用来找类,再来看访问权限。

其实java编译器是也没那么灵活,但是是很客观,理性得,只要你顺着逻辑思考,能搞懂java编译器这么工作得!


补充:

定义在域内和方法内的内部类,基本方法都要返回上层接口,因为,出了域内或者方法内就不可视,只能通过接口,然后多态来调用这个内部类!

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值