内部类

来源:互联网 发布:登陆传奇永恒网络异常 编辑:程序博客网 时间:2024/05/16 14:45
原版出处:百度传课《JavaSE轻松入门基础教程》 讲师:李伟


----概述:
一个类被嵌套定义在另一个类中,那么这个类就被称之为内部类,包含内部类的类就被称之为外部类。


----如何使用内部类:
1:
public class InnerTest{
 public static void main(String[] args){
  Outer out = new Outer; //现在外部类中定义一个调用内部类的方法,在通过此方法去访问内部类。
  out.useInner();
 }
}
public class Outer{
 private String out_string="这是外部类的一个私有属性";
 public void useInner(){
  Inner in = new Inner();
  in.print();
 }
 //创建内部类
 class Inner{
  public void print(){
  System.out.println(out_string); //内部类是可以访问外部类的私有属性的,因为私有的是本类可见。
  }
 }
}


2:
public class InnerTest{
 public static void main(String[] args){
 Outer out = new Outer;
 Outer.Inner in = out.new Inner();
 in.print(); //直接调用内部类
 }
}


注:
1:两种方法都必须先把外部类 new 一个出来。
2:内部类相当于外部类的成员变量或方法。


----匿名内部类
概念:就是没有名字的内部类


定义:
public class TestInner{
 public static void main(String[] args){
  OuterI outer = new OuterI(){  //利用内部类去实现接口
   public void show(){
    System,out,println("这是匿名内部类的show");
    }
   };   //注:此处有分号!因为此处定义了一个匿名内部类。
  outer.show();
 }
 interface OuterI{  //定义了一个接口
  public void show();
 }


}


----局部内部类
概念:
在类的局部位置(即方法)的进行定义的类叫做局部内部类。


特点:
1:在局部内部类里面可以访问外部类的所有成员变量。
2:局部内部类访问方法中的局部变量的时候,该局部变量必须声明为final类型。


拓展:为什么局部变量必须是final类型?
因为局部变量是随着方法而存在的,一旦方法被调用,则局部变量被启用,一旦方法调用结束,则局部变量被废弃。但是局部内部类的生命周期要比方法长(下例中:方法调用结束后,
oi还指向内部类,所以内部类还存在),方法调用结束时,局部内部类还存在,所以必须将局部变量声明为final类型(即变成常量)。






实例:
public class TestInner{
 public static void main(String[] args){
  Outer o = new Outer();
  OutI oi = o.eat(1); //oi指向了局部内部类
 }
}


public Outer{
 private String name;
 public OutI eat(final int i){ //返回值类型为OutI,Inner是OutI的实现,所以返回的new Inner(),就是OutI类型。 
  final int count = 0;
  class Inner implements OutI{
   public void innerEat(){
    System.out.println(name);
    System.out.println(i);   //参数会被赋值,所以不需要进行初始化。
    System.out.println(count); //需要被初始化 
   }
  }
  return new Inner(); //返回了一个OutI类型
 }
}


interface OutI{} //定义了一个接口


----静态内部类
概念:使用static修饰的内部类,称之为静态内部类。


特点:
1:在内部类前添加static修饰符。
2:静态内部类中可以声明static成员变量,非静态内部类中不可以。//因为静态内部类中的静态变量一旦被创建,那么它就存在了,而非静态内部类此时还没有存在。
3:静态内部类不可以使用外部类的非静态成员变量。//因为静态变量和非静态变量的生命周期是不一样的。
4:创建静态内部类的对象,不需要其外部类的对象。


形式:
1:创建非静态内部类的形式:
Outer o = new Outer();
Outer.Inner i = o.new Inner(); //使用了外部类的对象,对象被创建,表示外部类就被创建,外部类被创建后,才能被内部类访问。(外部类都没被创建,你内部类去访问个什么?)


2:创建静态内部类的形式:
Outer.Inner i = new Outer.Inner();


注:
1:内部类和外部类是同级的,在编译时内部类也会生成独立的class文件。
2:在内部类里面有对外部类的一个引用。


----引用外部类的对象
public class Outer{
 private int count = 1;
 class Inner{
  private int count = 2;
  public void print(int count){
   System.out.println(count);  //显示的是3  此处的count有个就近原则,先找本方法内的,在找内部类内的,最后再找外部类内的。(这是变量同名的情况下)
   System.out.println(this.count);  //显示的是2
   System.out.println(Outer.this.count);  //显示的是1
  }
 }
 public static void main(String[] args){
 Outer outer = new Outer();
 Outer.Inner i = outer.new Inner();
 i.print(3);
 }
}


总结:
调用方法里的:count
调用内部类里的:this.count
调用外部类里的:Outer.this.count


----内部类的继承
public class Test extends A.B{  //A.B表示继承的是A类中的B类。
 public Test(A a){     //相当于int i 
  a.super();        //调用A的构造方法,使外部类A实例化。
 }
}


class A{
  classB{
 }
}


详解:若Test要继承内部类B,那么使用Test的时候,内部类B将被实例化,而此时外部类A还未被实例化,所以需要先把外部类A实例化。





































0 0
原创粉丝点击