初学Java,内部类(十九)

25 篇文章 0 订阅

非静态内部类访问外部类同名实例属性

01.public class DiscernVariable   
02.{  
03.    private String prop = "外部类属性";  
04.    private class InClass  
05.    {  
06.        private String prop = "内部类属性";  
07.        public void info()  
08.        {  
09.            String prop = "局部变量";  
10.            //通过外部类类名.this.varName 访问外部类实例属性  
11.            System.out.println("外部类的属性值:" + DiscernVariable.this.prop);  
12.            //通过this.varName 访问内部类实例的属性  
13.            System.out.println("内部类的属性值:" + this.prop);  
14.            //直接访问局部变量  
15.            System.out.println("局部变量的值:" + prop);  
16.        }  
17.    }  
18.    public void test()  
19.    {  
20.        InClass in = new InClass();  
21.        in.info();  
22.    }  
23.    public static void main(String[] args)   
24.    {  
25.        new DiscernVariable().test();  
26.    }  
27.}  


 


非静态内部类可以访问外部类private实例属性,但是反过来外部类访问内部类的private实例属性就不行了,原因在于,内部类保有外部类的对象引用,而外部类没有内部类的引用

如果要访问内部类的实例属性, 可以这样 new Inner().inProp

编译上面的程序,文件所有路径会生成两个class文件,一个是DiscernVariable,一个是DiscernVariable$InClass.class

成员内部类(包括,静态,非静态)的class文件总是这种形式: OuterClass$InnerClass.class

Java不允许在非静态类里定义静态成员(静态方法,静态属性,静态初始化块)

如果是静态内部类,同样用static修饰,这个内部类与外部类相关,属于整个外部类,而不是单独属于外部类的某个对象,因此静态内部类称为类内部类,静态类不能访问外部类的实例成员,换句话说,就是不能访问非静态的成员,只要是静态的就是对类而言,非静态就是对类的实例而言,而且它们保存的内存位置也不相同,类保存在栈区,类的实例保存在堆区

如果在外部类以处使用非静态内部类,那么就不能对内部类使用private修饰符.因为非静态内部类的对象必须寄存在外部类的对象里,因此创建非静态内部类对象之前,必须先创建 其外部类的对象.

01.public class out   
02.{  
03.    //定义一个内部类,不使用访问控制符,即同一个包中其他类可访问该内部类  
04.    class In  
05.    {  
06.        public In(String msg)  
07.        {  
08.            System.out.println(msg);  
09.        }  
10.    }  
11.}  


 

01.public class CreateInnerInstance   
02.{  
03.    public static void main(String[] args)   
04.    {  
05.        Out.In in = new Out().new In("测试信息");  
06.        /* 
07.        上面代码可以改为如下三行代码 
08.        使用OuterClass.InnerClass 的形式定义内部类变量 
09.        Out.In in; 
10.        创建外部类实例,非静态内部类实例将寄存在该实例中 
11.        Out out = new Out(); 
12.        通过外部类实例和new来调用内部类构造器创建非静态内部类实例 
13.        in = out.new In("测试信息") 
14.        */  
15.    }  
16.}  


 

Out.In in = new Out().new In("测试信息"); 这样的写法真的让人觉得很怪异,但它就是合理的  


 

01.public class SubClass extends Out.In  
02.{  
03.    public SubClass(Out out)   
04.    {  
05.        //通过传入的Out对象显式调用In的构造器  
06.        out.super("hello");  
07.    }  
08.}  


 

非静态内部类In类的构造器必须使用外部类对象来调用,上面的super代表In类的构造器,真的很怪异的写法,不是吗?要使用内部类,必须先创建它的外部类

Java还支持在方法体里定义类,即局部类,就是局部变量一样,并可以定义局部类的子类,即继承一个局部类的另一个局部类

01.<pre class="java" name="code">public class LocalInnerClass   
02.{  
03.    public static void main(String[] args)   
04.    {  
05.        class InnerBase  
06.        {  
07.            int a;  
08.        }  
09.        class InnerSub extends InnerBase  
10.        {  
11.            int b;  
12.        }  
13.        InnerSub is = new InnerSub();  
14.        is.a = 5;  
15.        is.b = 8;  
16.        System.out.println("InnerSub对象的a和b属性是:" + is.a + "," + is.b);  
17.    }  
18.}</pre><strong><br><br></strong>  


输出 InnerSub对象的a和b属性是:5,8, 最后is对象也确实继承到父类的成员a

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值