java 内部类分为成员内部类,局部内部类,匿名内部类,

来源:互联网 发布:双色球出号绝密算法 编辑:程序博客网 时间:2024/06/18 08:48

**

内部类分为成员内部类,局部内部类,匿名内部类,

bagm:

一、 成员内部类即在成员变量处定义一个内部类,

1、内部类与外部类都可以彼此使用类中的方法,即使是 private 私有的
2、内部类的实例一定要在外部类的实例上,如果从外部类中初始化一个内部类,那么内部类就会绑定在外部类对象上,
3、在主方法中实例一个内部类对象,必须在new操作符前提供一个外部类的引用
并且不能使用外部类的类名,而要用外部内实例的对象来创建
4、非内部不能被声明为private 或 protected访问权限类型,
5、内部类可以实现多继承,以及内部类可以还有内部,(关于这两个用法见 附一内容)

 1. package StudyNBNBL;    class Abcd {         AbcdinnerClass abcdinnerClass = new AbcdinnerClass();         private int i = 0;         public class AbcdinnerClass {              // 成员内部类              private int o = 0;              private void print() {                   i = 100; // 可以随意使用外部类的私有成员                   System.out.println(i);                   System.out.println("内部类的abcdinnerClass");                   printll(); // 可以随意使用外部类的私有方法              }         }         public void printll() {              System.out.println("外部类的 printll");         }         public void printll2() {              abcdinnerClass.o = 100; // 外部类使用内部类的私用成员              System.out.println(abcdinnerClass.o);              abcdinnerClass.print(); // 调用内部类的方法         }         // 还回一个内部类的引用         public AbcdinnerClass ss() {              return new AbcdinnerClass();         } }    public class StudyNBNBL {         public static void main(String[] args) {              Abcd abcd = new Abcd();              abcd.printll();              abcd.printll2();              Abcd.AbcdinnerClass a = abcd.ss(); // 在类外实例化内部类方法1              Abcd.AbcdinnerClass a2 = abcd.new AbcdinnerClass(); // 在类外实例化内部类方法2              // 在主方法中实例一个内部类对象,必须在new操作符前提供一个外部类的引用 } }

二、使用接口,将一个权限为私有的内部类向上转型为接用,

1、如果将一个内部类权限为private的内部类向上转型为一个父类对象,或是接口时,在程序中将完成隐藏内部类的具体实现过程,
2、内部类的权限为private 所以除了外部类,其它类都不能防问到,
3、但是其它类可以访问到外部类的doit方法,它刚好返回一个内部类引用,
4、接口可以防部到内部类实现了接口的方法,但是方法的具体实现得到了很好的隐藏起来,这就是内部类的基本用法,
5、如果实现了接口的内部类中实现了该接口的方法,就可以定义多个内部类以不同的方式实现接口中的方法同一方法,而一般一个类不能多次实现接口中同一个方法的,

package StudyNBNBL;interface Out {     //定义了一个接口,准备接收私有内部类    public void outprint();}class Outclass {   // 外部类定义出来    private class Outinclass implements Out {  // 内部类定义出来,实现了Out接口         public void outprint() {   // 实现了接口,就实现方法            System. out.println("class outinprint --  out outprint");        }         public Outinclass(String s) {   //内部类构造方法,显于内部类已经构造完成            System. out.println(s);        }    }    public Outinclass doit() {   // 外部类方法,返回一个内部类的引用         return new Outinclass("实例化内部类,访问内部构造方法" );    }}public class Test2 {    public static void main(String[] args) {  // 在主方法中实现私有内部向上转型为接口        Outclass outclass = new Outclass();  // 先实列外部类对象         Out out = outclass.doit();           // 用接口的引用接用返回的内部类对象        out.outprint();                      // 使用接口调用内部实现的方法    }}

三、使用this处理外部类与内部类变量重名的方法

1、如果遇到外部类与内部类重名,可以用this方法解决,
2、使用就近原则
3、内部中使用this调用内部的变量X,使用类名加this的方法调用外部的变量
4、在内存中所有的对象都放置在堆中,方法以及方法中的形参或局部变量放置在栈中,

package StudyNBNBL;publicclass Test3 {    private int a = 0;    // 定义外部类的 a    private class Test3in {         private int a = 100;  // 定义了内部类的a         private void adoit (int a) {  // 方法中的形参也为a 是不是乱了            a++;             // 就近原则,形参的a加了             this.a ++;        // 内部类的a加了            Test3. this.a ++;  // 这个用了外部类名加this的当然是外部类的a加了        }    }}

附一: 内部类可以实现多继承,以及内部类可以还有内部 以及同名变量的调用方法使用

package StudyNBNBL;class AA {         // 定义第一个类    int i = 50;    public void aaprint () {        System. out.println("AA" );    }}class BB {        // 定义第二个类    int i = 40;    public void bbprint () {        System. out.println("BB" );    }}class CC extends AA{ // 定义一个类继承第一个类    int i = 10;     class CCin extends BB{// 定义内部类继承第二个类         int i = 20;         class CCinin {             int i =30;             public void CCininprint (){                 System. out.println("CCinin" );             }             public void CCininprint2(){  // 关于内部类多层,以及多继承的同名变量调用                 System. out.println(CC.this.i);                            System.out.println(CCin.this.i);                 System. out.println(i );  // 就近原则                 System.out.println(CCin.super.i);                 System. out.println(CC.super.i);             }         }     }}public class Test6 {    public static void main(String[] args) {  // 关于内部多层的申明        CC cc = new CC();        CC.CCin ccin = cc. new CCin();        CC.CCin.CCinin ccinin = ccin. new CCinin();        cc.aaprint();        ccin.bbprint();        ccinin.CCininprint();        CC.CCin.CCinin ccinin2 = new CC().new CCin().new CCinin();  // 一次申明最里面一层内部类的方法        ccinin2.CCininprint2(); // 测试关于内部类多层,以及多继承的同名变量调用            }}

四、局部内部类

1、即在方法中定义内部类与局部变量类似,方法中的内部类要先定义,后使用,
2、局部内部类不加修饰符,其范围为定义它的代码块
3、局部内部类不能定义静态变量,
4、可以访问外部类的局部变量,但是变量必须是final,(因为局部内部类生命周期的原因,造成访问已经不存在的变量)
5、可以访问外部类的成员变量,
6、变量同名参考this的用法,
7、在类外不能直接生成局部内部类(保证局部类对外不可见的)要想使用局部内部类需外部类对象或接口或使用向上转型,
8、局部类在方法中,该方法以外不能访问局部内部类的成员,
注:局部变量的生命周期与局部内部类对象的生命周期是不一样的,当局部变所处的函数(方法)执行结束后就已经不存在了,可局部内部类还可能一直存在(只要有引用该对象的变量)就会出现访问一个不存在的变量,

package StudyNBNBL;interface Out2{    public void show();}class Abcd2 {    int b = 100;    public Out2 f(final String X) {          final int a = 200;         class AbcdinnerClass implements Out2 {  // 不用加权限修饰符,其范围为代码块            AbcdinnerClass(String s) {                s = X;    // 只可以方问外部类final的局部变量                System. out.println(s);            }             public void show() {                System. out.println(a + " " + b );  // 可以方问外部类final的局部变量,以外部类的成员变量                System. out.println("Abcinshow" );            }        }         return new AbcdinnerClass( "f -- Abcin" );    }}public class Test4 {    public static void main(String[] args) {        Abcd2 abcd2 = new Abcd2();        Out2 out2 =abcd2.f( "no echo");        out2.show();    }}
0 0
原创粉丝点击