思否学否

Java 内部类,成员类,局部类,匿名类等

根据内部类的位置不同,可将内部类分为 :成员内部类与局部内部类。

class outer{
    class inner{//成员内部类
    }
    public void method() {
      class local_inner{ //局部内部类
        }
    }
}

1、成员内部类

(1)访问格式:

 外部类名.内部类名 对象名=外部类对象.内部类对象
//注意不要用中文全角空格,否则会出错!编译不通过!
class outer{
class inner{
public void show()
         {
            System.out.println("你好");
    }
 }
}
public class niming{
  public static void main(String[]args) {
    outer.inner b=new outer().new inner(); //创建对象访问对应内部类函数成员
    b.show(); }
}

 

虽然内部类可以以上述方式访问,但实际开发中,常将内部设为私有成员,以保护数据的安全,不让外部直接使用
(2)将内部类设为私有成员

class outer{
 //成员内部类,设为私有
private class inner{
  public void show() 
     { 
       System.out.println("你好"); } 
     }
  public void show1() { 
    inner b=new inner(); 
    b.show(); } 
   } 
 public class niming{ 
    public static void main(String[]args) {
         //创建对象访问对应内部类函数成员
        outer c=new outer();
           c.show1(); 
      } 
  }

 

(3)将内部类设为静态类

eg1:

 1 class outer{ 
 2     //静态成员变量 
 3     private static int num=20; 
 4     //静态成员方法 
 5     public static void show2() { 
 6         System.out.println("hello world");
 7      } 
 8     //成员内部类,设为私有静态 
 9     private static class inner{ 
10     public void show() { 
11         System.out.println(num); //静态内部类访问外部类成员时,只能访问外部类的静态成员
12         show2(); 
13         } 
14     } 
15     public void show1() {
16      inner b=new inner();
17      b.show(); 
18     } 
19 }
20  public class niming {
21      public static void main(String[]args) {
23       outer c=new outer(); 
24       c.show1(); 
25     } 
26 }                     

 

 

eg2:

eg3: Private 保证了数据的安全 ,Static 让数据访问更方便

 1 class Outer { 
 2 public int num = 10; 
 3 class Inner { 
 4 public int num = 20; 
 5 public void show() {
 6  int num = 30; 
 7 //三个变量对应的变量名相同
 8  //访问的是本方法中的num变量,满足就近原则 
 9 System.out.println(num); 
10 //通过this变量,访问方法外,本类中的变量,this代表Inner类对象 
11 System.out.println(this.num); 
12 //通过外部类名加this,返回外部类对象,访问对象外部类的
13 System.out.println(Outer.this.num);
14 //通过创建对象的方式访问外部成员变量不推荐 
15 //System.out.println(new Outer().num); }
16 }
17  } 
}
18 public class niming{ 19   public static void main(String[]args) { 20     Outer.Inner inner=new Outer().new Inner();
    inner.show();
21 } 22 }

 

2、局部内部类

 

public class Outer{ 
    int num1 = 1;
    static int num2=2;
    public void inner(){
    System.out.println("局部内部类");
    int num3 = 3;
   // static int num4=4; //error,不能用static修饰
        class InnerClass{   

//局部内部类的类体中不可以声明类变量和类方法,局部内部类不能用static修饰。成员内部类不存在这个限制。
        private int num5 = 5;
    //private static int num6 = 6; //error
        private final static int num7 = 7; //ok
    private static final int num8 = 8; //ok
    public void testNum()
         {
    System.out.println(num1);
    System.out.println(num2);
    System.out.println(num3);
    System.out.println(this.num5);//ok  
        }
     }
    InnerClass a=new InnerClass();
    a.testNum();
   }
public static void main(String[]args) { Outer c= new Outer(); c.inner(); }
}

 

成员内部类的字节码文件会不一样。会变成外部类名$number内部类名

 3、匿名内部类

匿名类,就是没有名称的类,其名称由Java编译器给出,一般是形如:外部类名称+$+匿名类顺序,没有名称也就是其他地方就不能引用,不能实例化,只用一次,当然也就不能有显式声明的构造函数.

  • 匿名类就是利用父类的构造函数和自身类体构造成一个类。

  • 匿名类可以继承父类的方法,也可以重写父类的方法。
  • 匿名类可以访问外部类的成员变量和方法,匿名类的类体不可以声明称static成员变量和static方法
  • 匿名类由于是一个new的结果,所以其实可以赋值给一个父类对象。因此可以分为两种匿名类,成员匿名类和局部匿名类(作为函数参数)
  • 匿名类永远不能是抽象的。
  • 匿名类总是隐式的final.
  • 匿名类总是一个内部类;并且不能是static的

 

编译时的命名规则:

  1. 内部类的class文件命名是:主类+$+内部类名
  2. 匿名类的class文件命名是:主类+$+(1,2,3….)

 

实际使用中我们只需注意这几点儿:
1. 使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。
2. 匿名内部类中是不能定义构造函数的。
3. 匿名内部类中不能存在任何的静态成员变量和静态方法。
4. 匿名内部类为局部内部类,所以局部内部类的所有限制同样对匿名内部类生效。
5. 匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。

访问权限
1. 访问外层Class里面的字段。
2. 不能访问外层方法中的本地变量。除非变量是final。
3. 如果内部类的名称和外面能访问的名称相同,则会把名称覆盖掉。
4. 不能定义静态初始化代码块
5. 不能在匿名类里面定义接口
6. 不能在匿名类中定义构造函数

实现接口方法的例子:

 


————————————————
版权声明:本文为CSDN博主「yin__ren」的原创文章,遵循undefined版权协议,转载请附上原文出处链接及本声明。
原文链接:https://blog.csdn.net/yin__ren/article/details/79177597

 

posted on 2019-11-30 14:51  思否学否  阅读(633)  评论(0编辑  收藏  举报