Java---内部类详解

  • 一、成员内部类
  • 二、方法内部类
  • 三、静态内部类
  • 四、匿名内部类
  • 五、总结


一、成员内部类

1、成员内部类的格式如下:

class Outer{
	class Inner{}
}

注意:在编译上述代码后会产生两个文件,一个是Outer.class文件一个是Outer$Inner.class文件
2、在外部创建内部类对象:内部类除了可以在外部类中产生实例化对象,也可以在外部类的外部来实例化对象,那么根据内部类生成的.class文件:Outer $Inner.class在程序运行时“ $”符号将替换成“.”,所以内部类的访问通过外部类.内部类的形式
代码示例:

public class Test {
	public static void main(Sring [] args) {
		Outer outer = new Outer();
		Outer.Inner inner = outer.new Inner();
		} 
}

通常情况下我们不使用这种方式来实例化内部类的对象,而是提供一个方法,对外提供访问接口。

二、方法内部类

1、内部类除了可以放在类的成员位置外,还可以在类的方法内定义
2、定义如下:

class Outer{
 public void show(){
	class Inner{
	public void print(){
		System.out.println(“我是内部类”);
	    }
	 }
   Inner inner = new Inner();
   Inner.print();
  }
}

注意:
① 方法内部类只能定义在该内部类的方法内实例化,不可以在此方法外对其实例化
② 方法内部类对象不能使用该内部类所在方法的非final局部变量

三、静态内部类

1、静态内部类是指在一个类中定义一个静态的内部类,静态的含义是该内部类可以像其他静态成员一样没有外部类对象时也能够访问它,静态内部类只能够访问外部类的静态成员和方法
2、静态内部类的格式:

class Outer{
	static class Inner{
		System.out.println(“我是静态内部类”);
	}
}
public class Test{
	public static void main(String [] args){
		Outer.Inner inner = new Outer.Inner();
		} 
}

注意:在静态内部类中无法引用非静态变量

四、匿名内部类

1、匿名内部类顾名思义就是没有名字的内部类啦!
2、匿名内部类分为三种:
① 继承式匿名内部类

public class NonameTest1 {
    public static void main(String [] args){
    //在这里继承抽象类,实际上就是一个类继承了这个抽象类,但是他没有名字(很抽象,要多理解)
        Employee employee = new Employee() {
        //重写抽象类类里面的抽象方法
            @Override
            public void sal() {
                System.out.println("继承式匿名内部类---发工资啦!");
            }
        };
        //调用匿名内部类的sal方法
        employee.sal();
        //-----------------------------------------------------------------
        //-----------------------------------------------------------------
        //这里还可以用匿名对象来操作
        new Employee() {
        //重写抽象类类里面的抽象方法
            @Override
            public void sal() {
                System.out.println("继承式匿名内部类---发工资啦!");
            }
        }.sal();
    }
}
abstract class Employee{
    abstract public void sal();
}

② 接口式匿名内部类

public class NonameTest1 {
    public static void main(String [] args){
    //接口是不能被实例化的,这里可以理解为是一个类实现了这个接口,但是这个类没有名字
        IAction iAction = new IAction() {
        //重写接口中的action方法
            @Override
            public void action() {
                System.out.println("接口式匿名内部类---开始工作啦!");
            }
        };
        //调用匿名内部类中的action方法
        iAction.action();
        //同样的道理,这里也可以用匿名对象来操作
    }
}
//定义一个接口
interface IAction {
    void action();
}

③ 参数式的匿名内部类

public class NonameTest1 {
    public static void main(String [] args){
        //先实例化一个对象
        Manager m = new Manager();
        //将接口式匿名内部类当作参数来传递
        m.manager(new IAction() {
        //重写接口中的action方法
            @Override
            public void action() {
                System.out.println("参数式匿名内部类---上班啦!");
            }
        });
    }
}
//定义一个Manager类
class Manager{
    public void manager(IAction iAction){
    //调用接口中的action方法
        iAction.action();
    }
}
//定义一个接口
interface IAction {
    void action();
}

3、(2)匿名内部类在使用时要注意的细节:
① 匿名内部类不能有构造方法,只能有一个实例
② 不能定义任何静态成员静态方法
③ 不能有public、protected、private、static关键字修饰
④ 一定是在new的后边用其隐含实现一个接口或者继承一个类
⑤ 匿名内部类为局部的所以局部内部类的所有限制都对其生效

五、总结

每个内部类都能独立地继承一个(接口)的实现,所以无论外部类是否已经继承了某个(接口的)实现对其内部类都没有影响。如果没有内部类提供的可以继承多个具体的或者抽象的能力,一些设计与编程问题就很难解决。从这个角度来看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”