内部类定义:一个外部类的内部再定义一个类,编译时的概念,一旦编译成功就与外围类属于两个完全不同的类。根据定义的结构的不同可以将内部类分成两种:成员式和局部式。然后成员式内部类又可以分为:静态内部类和成员内部类;局部式又可以分为:普通局部内部类和匿名内部类。具体介绍如下:
(1)静态内部类(也称嵌套内部类):定义在另一个类里面的类,前面多了一个关键字static【1)它的创建不需要依赖外围类;2)它不能使用任何外围类的非static成员变量和方法】
应用举例:
class Outter{
int a = 10;
static int b = 5;
public Outter(){
}
static class Inner{
public Inner(){
// System.out.println(a);
System.out.println(b);
}
}
}
public class StaticInnerClass {
public static void main(String[] args) {
Outter.Inner inner = new Outter.Inner();
}
}
所以从某种程度上来说,公开的静态内部类就相当于一个普通的类,与外部类仅仅是包含关系、缩小了命名空间而已(完整的类名中多了一个外部类的名称),本质上是两个独立的类,JVM也不知道他们两个有包含关系。
(2)成员内部类:最普通的内部类,是外围类的一个成员,可以无限制的访问外围类的所有成员属性和方法,但外围类要访问内部类需要通过内部类实例【成员内部类不能存在任何static变量和方法】
应用举例:
public class Circle {
double radius = 0;//外部类成员变量
public static int count = 1;
public Circle(double radius){//外部类成员方法
this.radius = radius;
getDrawInstance().drawShape();//外部类访问内部类必须先创建内部类对象,再通过对象访问
}
private Draw getDrawInstance(){//创建内部类对象
return new Draw();
}
class Draw{//内部类
public void drawShape(){//内部类方法
System.out.println(count++);//内部类可以无条件访问外部类成员
System.out.println(radius);//外部类的静态成员
System.out.println("InnerDraw");
}
}
public static void main(String[] args) {
//成员内部类依附于外部类存在,也就是说要创建成员内部类对象必须先创建外部类对象
//第一种方式:通过外部对象创建
Circle circle = new Circle(12);
Circle.Draw draw = circle.new Draw();
//第二种方式:通过外部对象调用外部成员方法创建
Circle circle1 = new Circle(112);
Circle.Draw draw1 = circle1.getDrawInstance();
}
}
(3)局部内部类:嵌套在方法和作用域内的,和成员内部类一样被编译但作用域只能在该方法和属性中被使用,出了该方法就会失效【局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的】
应用举例:
//定义在方法里
public class PartInnerClass {
public Destination destination(String s) {
class PDestination implements Destination {
private String label;
private PDestination(String whereTo) {
label = whereTo;
}
public String readLabel() {
return label;
}
}
return new PDestination(s);
}
public static void main(String[] args) {
PartInnerClass part = new PartInnerClass();
Destination destination = part.destination("Test");
}
}
//定义在作用域里
public class PartInnerClass{
private void internalTracking(boolean bool){
if(bool){
class TrackingSlip{
private String id;
TrackingSlip(String str){
id = str;
}
String getSlip(){
return id;
}
}
TrackingSlip ts = new TrackingSlip("slip");
String str = ts.getSlip();
}
}
public void track(){
internalTracking(true);
}
public static void main(String[] args) {
PartInnerClass part = new PartInnerClass();
part.track();
}
}
(4)匿名内部类:即没有名字的内部类(不出现class关键字),一般用于继承其他类或是实现接口,不需要增加额外的方法只是对继承的方法重写或是实现【没有构造函数、没有访问修饰符的内部类】
应用举例:
public class AnonymousClass {
interface InnerClass{
int getNumber();
}
public InnerClass getInnerClass(final int num, String str){
return new InnerClass(){
int number = num + 3;
public int getNumber(){
return number;
}
};//分号不能丢
}
public static void main(String[] args) {
AnonymousClass out = new AnonymousClass();
InnerClass inner = out.getInnerClass(2, "Test");
System.out.println(inner.getNumber());
}
}
总结:
1、静态内部类:相当于外部类的静态成员一样,使用static修饰的内部类,虽隶属于外部类,但使用起来相当于一个独立的外部类;
2、成员内部类:相当于外部类普通的成员一样,隶属于外部类的具体对象,在定义它的时候需要先创建外部类对象,再创建它的实例;
3、局部内部类:它定义在一个方法的方法体中,它往往仅作为方法短暂的使用;
4、匿名内部类:定义在方法体中,但是没有一个具体的名字,具有非常大的灵活性;