关于内部类

来源:互联网 发布:云计算国家政策 编辑:程序博客网 时间:2024/05/07 16:04

对内部类用的少,基本上都有点陌生了。今天看到一个博客感觉还不错就转了过来。先谢谢博主!!!

1.关于内部类的说明
1)在一个类中定义另外一个类,这个类就叫做内部类(inner class) 。内部类的定义和普通类的定义没什么区别,它可以直接访问和引用它的外部类的所有变量和方法(包括private),就像外部类中的其他非static成员的功能一样。区别是,外部类只能声明为public和default,而内部类可以声明为private和protected。 中国自学编程网 www.zxbc.cn
 
2)当我们建立一个inner class时,其对象就拥有了与外部类对象之间的一种关系,这是通过一个特殊的this reference形成的,当内部类的成员方法中访问某个变量/方法时,如果在该方法和内部类中都没有定义过这个变量,调用就会被传递给内部类中保存的那个外部类对象的引用(OuterClass.this),通过那个外部类对象的引用去调用这个变量。
 
2.内部类变量访问
2.1在main中直接从外部类调用内部类的方法
package org.zj.sample;
class Outer {
    private int index = 100;
    class Inner {
         private int index = 50;
         void print() {
           int index = 30;
           System.out.println(index); // 30
           System.out.println(this.index); // 50
           System.out.println(Outer.this.index); // 100
         }
}
 
    void print() {
         Inner inner = new Inner();//得到内部类的引用
         inner.print();
    }
}
 
class Test {
    public static void main(String[] args) {
         Outer outer = new Outer();
         outer.print();
    }
}

该示例程序列出了重名成员变量分布的3种情况。
访问内部类方法中的变量:
System.out.println(index);

访问内部类中的成员变量:
System.out.println(this.index);

访问所在外部类的成员变量:
System.out.println(Outer.this.index);

 
2.2在main中显式返回内部类引用
package org.zj.example;
class Outer {
    private int index = 100;
class Inner {
         private int index = 50;
         void print() {
           int index = 30;
           System.out.println(index); // 30
           System.out.println(this.index); // 50
           System.out.println(Outer.this.index); // 100
         }
}
 
    Inner getInner() {
         return new Inner();//返回一个内部类的引用
    }
}
 
class Test {
    public static void main(String[] args) {
         Outer outer = new Outer();
         Outer.Inner inner = outer.getInner();
         inner.print();
    }
}

 
2.3当main方法在Outer类内部
package org.zj.sample1;
class Outer {
    private int index = 100;
    class Inner {
         private int index = 50;
         void print() {
           int index = 30;
           System.out.println(index); // 30
           System.out.println(this.index); // 50
           System.out.println(Outer.this.index); // 100
         }
    }
 
    Inner getInner() {
         return new Inner();
    }
 
    public static void main(String[] args) {
Outer outer = new Outer();
         Inner inner = outer.getInner(); // 注意此处变化
         inner.print();
    }
}

 
2.4在main方法中直接产生内部类对象
package org.zj.sample2;
class Outer {
    private int index = 100;
    class Inner {
         private int index = 50;
         void print() {
           int index = 30;
           System.out.println(index); // 30
           System.out.println(this.index); // 50
           System.out.println(Outer.this.index); // 100
         }
}
}
 
class Test {
    public static void main(String[] args) {
         Outer outer = new Outer();
         Outer.Inner inner = outer.new Inner(); // 注意此处变化
         inner.print();
    }
}

 
2.5在方法中定义内部类
在方法中定义的内部类只能访问方法中的final类型的局部变量,因为用final定义的局部变量相当于是一个常量,它的生命周期超出方法运行的生命周期。而且方法体中的内部类不能有访问说明符。
package org.zj.sample;
class InOut {
    String str=new String("Between");
    public void amethod(final int aArgs){
         class Inner{
        public Inner(){
          System.out.println("This is Inner.");//此句可看出它与匿名内部类用法的不同。
        }
           public void sayHello(){
System.out.println(str);
                System.out.println(aArgs);
           }
       }
    Inner inner=new Inner();//此句必须放在定义类Inner的后面
       inner.sayHello();
    }
    
    public static void main(String[] args){
         InOut inOut=new InOut();
         inOut.amethod(33);
    }
}

在方法体中使用内部类可以使用一个已命名的构造子,或重载构造子。而匿名内部类只能用于实例初始化。
 
3.内部类的继承
当一个类继承自一个内部类时,缺省的构造器不可用。必须使用如下语法:
enclosingClassReference.super();(见下例绿色部分)
package org.zj.sample;
class WithInner{
    class Inner{
         public void sayHello(){
           System.out.println("Hello.");
         }
    }
}
public class InheritInner extends WithInner.Inner {
    InheritInner(WithInner wi){
         wi.super();
    }
    public static void main(String[] args) {
         WithInner wi=new WithInner();
         InheritInner ii=new InheritInner(wi);
         ii.sayHello();
    }
}

 
结果:
Hello.
 
4.匿名内部类
未使用匿名内部类的情况:这里单独写了一个内部类Inner。
package org.zj.example;
abstract class A{
    abstract public void sayHello();
}
 
class Outer {
    public static void main(String[] args){
       class Inner extends A{
           public void sayHello(){
   System.out.println("Hello!");
           }
       }
       new Outer().callInner(new Inner());
    }
    
    public void callInner(A a){
         a.sayHello();
    }
}

使用匿名内部类的情况:直接在new A()中给出Inner的定义。
package org.zj.example;
abstract class A{
    abstract public void sayHello();
}
 
class Outer {
    public static void main(String[] args){
       new Outer().callInner(new A(){
           public void sayHello(){
              System.out.println("Hello!");
           }
       });
    }
    
    public void callInner(A a){
         a.sayHello();
    }
}

 
5.内部类的2种特殊用法
一个类从另一个类派生出来,又要实现一个接口。但在接口中定义的方法与父类中定义的方法的意义不同,则可以利用内部类来解决这个问题。
package org.zj.sample;
interface Machine {
    void run();
}
 
class Person {
    void run() {
         System.out.println("run");
    }
}
 
class Robot extends Person {
    private class MachineHeart implements Machine {
         public void run() {
           System.out.println("heart run");
         }
    }
 
    Machine getMachine() {
         return new MachineHeart();
    }
}
 
class Test {
    public static void main(String[] args) {
         Robot robot = new Robot();
         Machine m = robot.getMachine();
         m.run();
         robot.run();
    }
}

在Robot类内部使用内部类MachineHeart来实现接口Machine的run方法。同时Robot类又继承了父类Person的run方法。如果不使用内部类MachineHeart而使Robot直接实现接口Machine,则该如何调用父类的run方法?
 
利用内部类可解决c++中多重继承所解决的问题
package org.zj.example;
class A {
    void fn1() {
       System.out.println("It’s fn1.");
    }
}
 
abstract class B {
    abstract void fn2();
}
 
class C extends A {
    B getB() {
       return new B() {
           public void fn2() {
              System.out.println("It’s fn2.");
           }
       };
    }
}
 
class Test {
    public static void main(String[] args) {
       C c = new C();
       c.fn1();
       c.getB().fn2();
    }
}

类C既要继承类A又要继承类B,则可将类B的定义放入类C内部,使之成为内部类。
 
6.我们为什么使用内部类
这是对上一章节两种用法的总结,可结合上一章节的两个实例分析。
1)  当我们需要在某一情形下实现一个接口,而在另一情形下又不需要实现这个接口时,我们可以使用内部类来解决这一问题。让内部类来实现这个接口。
2)  内部类有效的解决了多重继承的问题。


本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/armyjian/archive/2007/11/05/1867936.aspx

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 在拆违通知书上签字了该怎么办 单位没交公职金的退休后怎么办 公租房合同到期后没有续签怎么办 租房合同没到期不想租了怎么办 租的房子是人家公租房怎么办 五险合一软件口令忘记了怎么办 计生办把婚育状况登记错了怎么办? 医院发票法院要保险也要怎么办 上海社保里生育险暂停参保怎么办? 痔疮手术后大姨妈来了怎么办 微创痔疮术后第五天涨出血怎么办? 肚子胀疼大便拉不出来怎么办 得痔疮了该怎么办昆明东大治 下体痒还没去检查就来月经了怎么办 直肠造口手术后造口肠子突出怎么办 痔疮pph手术瘢痕两年了该怎么办 肛瘘挂线术后六天腹泻了怎么办 刚满月的孩子鼻子不通气怎么办 齐鲁医院挂的号晚了怎么办 手机微信安装后注册失败怎么办 舞蹈基本功胸怎么都转不动怎么办 饥荒手机版第10天遇到的狗怎么办 饥荒海难手游石墙老是放歪怎么办 小燕子从窝里掉下来了怎么办 二岁宝宝晚上睡觉不踏实怎么办 脚扭伤了有点痛但没肿该怎么办 落地扇的机头摇摆的地方坏了怎么办 跌倒在楼梯上右侧肋骨骆上怎么办 1岁3个月害怕自己不敢走路怎么办 苹果手机没开定位丢了怎么办 我和我老婆每天都吵架怎么办 现在在学注册消防师好枯燥怎么办 店铺台阶太高顾客不愿进来怎么办? 上古卷轴5跑步要沉下去怎么办 1岁半宝宝半夜醒来不睡觉怎么办 上古卷轴5不小心偷了东西怎么办 47牙缺失17号长长了怎么办 碎纸机过热件亮了卡住纸了怎么办 汽车买贵了2万多怎么办 宝宝眼皮被蚊子咬肿了怎么办 一岁宝宝撞头咬到舌头有伤口怎么办