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

**

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

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();
    }
}
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值