Java四种内部类

内部类分为四种:

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=5
finalLocalVar=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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值