Java四种内部类

来源:互联网 发布:lol mac国服 编辑:程序博客网 时间:2024/06/03 14:59

内部类分为四种:

1.成员内部类
2.局部内部类
3.静态内部类
4.匿名内部类

(一)实现方式:

1.成员内部类

//成员内部类......相当于非静态方法class MemberInner {  private int a = 2;  public class Inner2 {      private int a =3 ;      public void doSomething(int a) {          // 调用外部类的属性          System.out.println(MemberInner.this.a);// 这块要注意......很重要!!!输出结果为:2          System.out.println(this.a);//输出结果为:3         // 调用局部属性          System.out.println(a);//输出结果为:5      }  }}public class Test3 {  public static void main(String[] args) {      MemberInner.Inner2 inner2 = new MemberInner().new Inner2();// 非静态内部类要new实例      inner2.doSomething(5);  }}

2.静态内部类

//静态内部类......相当于静态方法class StaticInner{  private static int a=3;  public static class Inner{      public void test(){          System.out.println(a);      }  }}public class Test2 {  public static void main(String[] args) {      StaticInner.Inner inner=new StaticInner.Inner();//静态内部类直接调用      inner.test();  }}

3.局部内部类

//局部内部类......相当于局部变量class LocalInner {  public void doSomething(int b) {      final int a = 3;// 只能访问final的变量      class Inner3 {          public void test(int b) {              System.out.println(b);//输出结果:4              System.out.println(a);//输出结果:3          }      }      new Inner3().test(b);  }}public class Test4 {  public static void main(String[] args) {      LocalInner inner = new LocalInner();      inner.doSomething(4);  }}

4.匿名内部类

public class NiMing {    private int size=5;    public Object makeInner(int localVar){        final int finalLocalVar=localVar;        return new Object(){             //使用匿名内部类             public String toString()             {             return "OuterSize="+size+"\nfinalLocalVar="+finalLocalVar;             }         };    }    public static void main(String args[])    {        Object obj=new NiMing().makeInner(47);        System.out.println(obj.toString());    }}//输出结果为:OuterSize=5finalLocalVar=47

(二)四种内部类介绍:

什么时候需要使用内部类?
当描述事物时,事物的内部还有事物,在内部的事物就用内部类来描述,因为内部事物需要使用外部事物的内容。

内部类的访问规则:
1. 内部类可以直接访问外部类的成员,包括私有。之所以可以直接访问外部类的成员,是因为内部类中持有外部类的引用,格式:外部类名.this
2.外部类要访问内部类,必须建立内部类对象。

四种内部类介绍:

1.成员内部类:当内部类定义在外部类的成员位置上就称为成员内部类。

可以在外部其他类中,直接建立内部类的对象。
格式:外部类名.内部类名 变量名=外部类对象.内部类对象;如:Outer.Inner in=new Outer().new Inner();

2.静态内部类:当内部类在成员位置上,就可以被成员修饰符所修饰。比如private:将内部类在外部类中进行封装。static:内部类就具备了static的特性。当内部类被static修饰后,就成为了静态内部类。

在外部其他类中,如何直接访问static内部类的静态成员呢?

Outer.Inner.function();(Inner 是静态的,可以直接通过外部类名Outer来访问;function也是静态的,可以直接通过其所在类的类名Inner访问。)

注意:
1)静态内部类只能访问外部类的静态成员。
2)如果在内部类中定义了静态成员,则该内部类必须也是静态的。
3)当外部类中的静态方法中需要访问内部类时,内部类必须也是static的。
总的来说就是那个比较常见的提示:“不能在静态上下文中引用非静态变量”。

3.局部内部类:因为内部类可以定义在外部类中任意的位置,当内部类被定义在局部时(比如在方法中)就称为局部内部类。

注意:
1)不可以被成员修饰符修饰。
2)可以直接访问外部类中的成员,因为还持有外部类的引用。
但不可以访问它所在的局部区域中的变量,除非该变量被final修饰。

4.匿名内部类:匿名内部类也就是没有名字的内部类,正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写

使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口

实例1:不使用匿名内部类来实现抽象方法

abstract class Person {
public abstract void eat();
}

class Child extends Person {
public void eat() {
System.out.println(“eat something”);
}
}

public class Demo {
public static void main(String[] args) {
Person p = new Child();
p.eat();
}
}
运行结果:eat something

可以看到,我们用Child继承了Person类,然后实现了Child的一个实例,将其向上转型为Person类的引用

但是,如果此处的Child类只使用一次,那么将其编写为独立的一个类岂不是很麻烦?

这个时候就引入了匿名内部类

实例2:匿名内部类的基本实现

abstract class Person {
public abstract void eat();
}

public class Demo {
public static void main(String[] args) {
Person p = new Person() {
public void eat() {
System.out.println(“eat something”);
}
};
p.eat();
}
}
运行结果:eat something

可以看到,我们直接将抽象类Person中的方法在大括号中实现了

这样便可以省略一个类的书写

并且,匿名内部类还能用于接口上

实例3:在接口上使用匿名内部类

interface Person {
public void eat();
}

public class Demo {
public static void main(String[] args) {
Person p = new Person() {
public void eat() {
System.out.println(“eat something”);
}
};
p.eat();
}
}
运行结果:eat something

由上面的例子可以看出,只要一个类是抽象的或是一个接口,那么其子类中的方法都可以使用匿名内部类来实现

最常用的情况就是在多线程的实现上,因为要实现多线程必须继承Thread类或是继承Runnable接口

实例4:Thread类的匿名内部类实现

public class Demo {
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.print(i + ” “);
}
}
};
t.start();
}
}
运行结果:1 2 3 4 5

实例5:Runnable接口的匿名内部类实现

public class Demo {
public static void main(String[] args) {
Runnable r = new Runnable() {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.print(i + ” “);
}
}
};
Thread t = new Thread(r);
t.start();
}
}
运行结果:1 2 3 4 5

原创粉丝点击