Java内部类
一、定义
1、即在一个类的内部定义的另一个类,内部类能直接访问外部内的所有变量,即可与外部类链接保持通信;内部类提供了某种进入其外部类的容器。
2、使用内部类的一大原因是:内部类能独立地继承自一个接口的实现,而无论外部类是否已经继承,对于内部类都没有影响。这间接实现了继承多个类。
3、内部类可以在一个类、方法等任意作用域内定义
4、在另一个类里实例一个类的非静态内部类使用.new。拥有外部类对象之前是不可能创建内部类对象的,所以需要先实例外部类。如果内部类是静态类,则和普通的静态类一样,可以直接调用。
5、接口中的内部类, 接口中可以放置内部类,接口中的任何类都自动是public static的,所以相当于放置了一个static公共方法;
6、内部类是面向对象的闭包
7、内部类可以被继承,继承时不用继承外部类;
8、内部类被编译后会生成一个独立的.class文件,命名规则为:外部类的名字加上$,再加上内部类的名字。如果内部类是匿名的,编译器会简单的生成一个数字作为其标识符。
示例:
public class StudyTest { StudyTest(){ System.out.println("construct StudyTest"); } private String study = "study"; public class InnerClass{ public StudyTest outClass(){ System.out.println(study); return StudyTest.this; //使用.this直接调用当前类的父类 } } public static void main(String[] args) { InnerClass innerClass = new StudyTest().new InnerClass(); //实例内部类 innerClass.outClass(); } }
运行结果:
construct StudyTest
study
二、应用
1、内部类用于隐藏实现细节示例
接口与调用:
public interface StudyInterface { String getValue(); } public class MainClass { public static void main(String[] args) { StudyInterface studyInterface = new StudyTest().instance(); System.out.println(studyInterface.getValue()); } }
实现:
public class StudyTest { StudyTest(){ System.out.println("construct StudyTest"); } private String study = "study"; //此内部类对外不可见,不可实例不可继承. private class InnerClass implements StudyInterface{ @Override public String getValue() { return study; } } public StudyInterface instance(){ return new InnerClass(); } }
通过这种方式可以完全阻止任何依赖于类型的编码,并且完全隐藏了实现细节。从调用方的角度看,由于不能访问任何新增加的、原本不属于公共接口的方法,所以扩展接口是没有价值的。
2、匿名内部类
public class StudyTest { private String name = "study"; public String getName(){return this.name;} } public class MainClass { public StudyTest studyTestPlus(){ return new StudyTest(){ private String nameplus = "studyTestPlus"; public String getName(){return nameplus;} }; //注意此处有分号,不能省略 } public static void main(String[] args) { StudyTest studyTest = new MainClass().studyTestPlus(); System.out.println(studyTest.getName()); } //----------studyTestPlus()处相当于对StudyTest类进行了继承拓展,效果和下边的代码一样:---------- public class StudyTestPlus extends StudyTest{ private String nameplus = "studyTestPlus"; public String getName(){return nameplus;} } public StudyTest studyTestPlus(){ return new StudyTestPlus(); }
匿名内部类既可以扩展类,也可以实现接口,但不能两者兼备,如果实现接口也只能实现一个。
3、匿名内部类与工厂模式结合
public interface Service{ void printName();} public interface ServiceFactory{Service getService();} public class Factory{ public static void serviceConsumer(ServiceFactory factory){ factory.getService().printName(); } } public class Implements1 implements Service{ public void printName(){System.out.println("Implements1");} public static ServiceFactory factory =new ServiceFactory() { public Service getService() { return new Implements1(); } }; } public class Implements2 implements Service{ public static ServiceFactory factory =new ServiceFactory() { public Service getService() { return new Implements2(); } }; }
//使用 public static void main(String[] args) { Factory.serviceConsumer(Implements1.factory); Factory.serviceConsumer(Implements2.factory); }