A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

本帖最后由 吉山小学生 于 2018-1-17 10:06 编辑

内部类的概念和创建
概念 :内部类就是将一个类的定义置于另一个类的定义的内部。
[Java] 纯文本查看 复制代码
1

public class Outer{
  
   class Inner{
   }
 
}

如上面的例子:类Inner的定义放在类Outer的定义的内部了。

那么如何来创建内部类对象呢?

内部类对象的创建必须依赖外围类的对象!
[Java] 纯文本查看 复制代码
Outer outerObj = new Outer();//创建外围类的对象
Outer.Inner innerObj = outerObj.new Inner();//创建内部类对象
//如果通过上述的方式创建内部类不需要import内部类.


另外一种方式
[Java] 纯文本查看 复制代码
Outer outerObj = new Outer();//创建外围类的对象
Inner innerObj = outerObj.new Inner();//创建内部类对象

//如果是上述方式这么写,那么在该文件导包导入该内部类。比方Outer类在包coding.me中,则需要像下面这样导包
// import coding.me.Outer.Inner


内部类和外部类的链接
  当一个外部类的对象创建一个内部类对象时,此内部类对象会捕获一个指向外部类对象的引用,我们可以在内部类中使用OuterClassName.this来获得对外部类对象的引用。而且内部类拥有对外部类所有成员的访问权限
         1.内部类访问外部类的成员变量
        
[Java] 纯文本查看 复制代码
public class Outer{
  
  public String member1 = "成员_one";
  
   class Inner{
     
     //内部类的成员方法
     public void inner_method1 {
        //访问外围类的成员变量---member1
       System.out.println("外部类的成员:" + member1);
     }
  
   }
 
}
​


[Java] 纯文本查看 复制代码
public class Test {
  
  public static void main(String[] args){
    
    Outer outerObj = new Outer();//创建外部类的对象
    
    Outer.Inner innerObj = outerObj.new Inner();//创建内部类对象
    
    innerObj.inner_method1();
    
  }
 
  
}

结果:外部类的成员:成员_one


在上面的例子中我们看到:在内部类Inner中可以直接访问外部类Outer的成员member1而不加任何修饰和限定。但是如果内部类Inner中同样也有一个名为member1的成员呢,我们该怎么来区分?看下面的例子:


[Java] 纯文本查看 复制代码
public class Outer{
  
    //外部类的成员  
    public String member1 = "outer_成员_one";

     class Inner{

         //内部类的成员
         public String member1 = "inner_成员_one";

         //内部类的成员方法
         public void inner_method1 {

              //访问外部类的成员变量---member1
             System.out.println("外部类的成员:" + Outer.this.member1);
           
             //访问内部类的成员变量---member1
             System.out.println("内部类的成员:" + member1);
         }

     }
 
}

public class Test {
  
  public static void main(String[] args){
    
    Outer outerObj = new Outer();//创建外部类的对象
    
    Outer.Inner innerObj = outerObj.new Inner();//创建内部类对象
    
    innerObj.inner_method1();
    
  }
 
  
}

 结果:外部类的成员:outer_成员_one
       内部类的成员:inner_成员_one


2.内部类访问外部类的成员方法
    在内部类中访问外部类的成员方法与访问成员变量一样,不在赘述!
局部内部类 通过上面对内部类都是定义在外部类的类中方法外,内部类可以定义方法里面(其实内部类可以定义类中的任何作用域中)。定义在方法中的内部类称为局部内部类
[Java] 纯文本查看 复制代码
public class Outer {
  
          int i = 12;
  
     public void outer_method1() {

          int i = 10;

          //局部内部类
          class LocalInner{

               int i = 11;//如果注释掉这行代码,输出结果怎样?
              public void localInner_method1() {
                  System.out.println("局部内部类:localInner" +","+ "局部变量:"+ i );
                  System.out.println("局部内部类:localInner" +","+ "内部类成员变量:"+ this.i );//如果注释掉 int i = 11,这行代码编译错误 
                  System.out.println("外部类:Outer" +","+ "外部类成员变量:"+ Outer.this.i );

              }


          }


          LocalInner localInner_obj = new LocalInner();

          localInner_obj.localInner_method1();

      }
  
 
  
}

class Test {
  
    public static void main(String[] args){

          Outer outerObj = new Outer();
              outerObj.outer_method1();

    }
  
  
 }

结果:局部内部类:localInner,局部变量:11 //根据输出的结果发现,局部变量并不是10,而是内部类的成员11
     局部内部类:localInner,内部类成员变量: 11
     外部类:Outer,外部类成员变量: 12
  /*根据输出的结果,可知当局部内部类的成员变量和方法内的局部变量同名时,我们是无法区分的!*/
       
  //如果注释掉局部内部类中的 int i = 11;这行的代码,则输出结果为:
   局部内部类:localInner,局部变量:10    
   外部类:Outer,外部类成员变量: 12
  /*如果注释掉 int i = 10;*/


如上所示,内部类LocalInner定义在方法内部,LocalInner既为局部内部类,而且LocalInner只能在方法outer_method1中使用。对于局部内部类的使用有两点需要注意:
  • 如果局部内部类截获了,局部变量! 那么这个局部变量就会变成常量,即变量会被final修饰限制
  • 局部内部类不能有权限修饰符。



匿名内部类
[Java] 纯文本查看 复制代码
public class A {
  
   public static void main(String[] args){
    
      B obj_b = new B();
      obj_b.method_b();
    
   }
  
  
    public int value(){
      
      System.out.println("A类的方法");
      return 1;
      
    }
 
}

class B {
  
  public void method_B () {
    
    A obj_a = new A(){
      
          private int a_member = 12;
      
          public int value(){

            System.out.println("A类的子类重写的方法");
              return 10;
          }
  
      };
      
      obj_a.value();
     
    } 
  }
}

//运行结果为:A类的子类重写的方法
类B的成员方法method_b()中的代码有点奇怪,它即创建对象,又有类的定义。这种语法真正的含义是:创建一个继承A类的子类对象,但是这个子类(匿名类)没有名字 。new A()后面的代码即为该子类的定义。创建的这个对象的引用向上转型为父类类型(A)。

上面在创建匿名内部类对象时,使用的无参构造new A(),如果需要父类的参构造怎么办?

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
public class A {
  
   public static void main(String[] args){
    
      B obj_b = new B();
      obj_b.method_b();
    
   }
   
  public A (int x){
      System.out.println("有参构造:参数" + x);
  }
  
    public int value(){
      
      System.out.println("A类的方法");
      return 1;
      
    }
 
}

class B {
  
  public void method_B () {
    
    int i = 10;
    
    A obj_a = new A(i){
      
          private int a_member = 12;
      
          public int value(){

            System.out.println("A类的子类重写的方法");
              return 10;
          }
  
      };
      
      obj_a.value();
     
    } 
  }
}

//运行结果:有参构造:参数10
//         A类的子类重写的方法




1 个回复

倒序浏览
我来占层楼啊   
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马