1、内部类的定义:
一个内部类可以定义在另一个类里,可以定义在函数里,甚至可以作为一个表达式的一部分。
2、内部类的分类:
Java中的内部类共分为四种:
成员内部类member inner class
局部内部类local inner class
匿名内部类anonymous inner class
静态内部类static inner class
2.1、成员内部类member inner class
成员内部类是最普通的内部类,它的定义为位于另一个类的内部
package inner; public class Outer {// 外部类 String outerLabel = "outer"; private int i = 1; static int j = 11; public void printOuterLabel(){ System.out.println(outerLabel+"\t"+i+"\t"+j); } class Inner{// 内部类 String innerLabel = "inner"; public void printInnerLabel(){ System.out.println(outerLabel+"\t"+innerLabel+"\t"+i+"\t"+j); } } // 外部类调用内部类的引用,需要通过new关键字新建对象 public void printInner(){ Inner inner = new Inner(); inner.printInnerLabel(); } public static void main(String[] args){ Outer outer = new Outer(); outer.printOuterLabel(); outer.printInner(); } }
输出
outer 1 11
outer inner 1 11
说明:
1.内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。
2.内部类的对象只有在与其外部类的对象相关联的情况下才被创建
3.当内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是内部类的成员
当内部类需要访问外部类同名变量或者方法的时候,通过下面方法
外部类.this.成员变量 外部类.this.成员方法
package inner; public class Outer {// 外部类 String Label = "outer"; private int i = 1; static int j = 11; public void printLabel(){ System.out.println(Label+"\t"+i+"\t"+j); } class Inner{// 内部类 String Label = "inner"; public void printLabel(){ // 内部类中调用外部类的同名变量、方法 System.out.println(Outer.this.Label+"\t"+Label+"\t"+i+"\t"+j); Outer.this.printLabel(); } } // 外部类调用内部类的引用,需要通过new关键字新建对象 public void printInner(){ Inner inner = new Inner(); inner.printLabel(); // 内部类的方法 } public static void main(String[] args){ Outer outer = new Outer(); outer.printLabel(); outer.printInner(); } }
输出
outer 1 11 outer inner 1 11 outer 1 11
在内部类需要生成外部类对象的引用,可以下面方法
外部类.this
这里在内部类获取了外部类的引用,就可以很方面的操作外部类
package inner; public class Outer {// 外部类 String Label = "outer"; private int i = 1; static int j = 11; public void printLabel(){ System.out.println(Label+"\t"+i+"\t"+j); } class Inner{// 内部类 public Outer outer(){ return Outer.this; } } // 外部类 返回内部类的引用 public Inner inner(){ return new Inner(); } public static void main(String[] args){ Outer outer = new Outer(); Outer.Inner inner = outer.inner(); inner.outer().printLabel(); } }
当其他对象要创建内部类的对象时候需要通过
new 外部类().new 内部类()
package inner; public class Outer {// 外部类 String Label = "outer"; private int i = 1; static int j = 11; public void printLabel(){ System.out.println(Label+"\t"+i+"\t"+j); } class Inner{// 内部类 public Outer outer(){ return Outer.this; } } // 外部类 返回内部类的引用 public Inner inner(){ return new Inner(); } public static void main(String[] args){ Outer outer = new Outer(); Outer.Inner inner = outer.new Inner(); inner.outer().printLabel(); } }
输出和上面一样
通过.new 访问内部类,而内部类又是返回外部类的对象,通过这个对象我们就可以很方面的操作外部类的对象,变量等。
2.2、局部内部类local inner class
在方法的作用域内创建的一个完整类,称为局部内部类
package inner; public class Parcel2 {// 外部类 public Destination destination(String s){ // 方法内 class PDestination implements Destination{ // 方法内的内部类-->局部内部类 private String label; private PDestination(String to){ this.label = to; } public String readLabel(){ return label; } } return new PDestination(s); } public static void main(String[] args) { Parcel2 p = new Parcel2(); Destination d = p.destination("label"); System.out.println(d.readLabel()); } }
接口
package inner; public interface Destination { String readLabel(); }
输出
label
局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。
局部内部类属于其所在的方法,不属于外部类
2.3、匿名内部类anonymous inner class
接口
package inner; public interface Contents { int value(); }
package inner; public class Parcel7 { public Contents contents(){ // contents 方法将返回值的生成与表示这个返回值的类的定义结合在一起 return new Contents(){ private int i = 10; public int value(){ return i; } }; } public static void main(String[] args){ Parcel7 p = new Parcel7(); Contents c = p.contents(); System.out.println(c.value()); } }
建立匿名内部类的关键点是重写父类的一个或多个方法。
上面匿名内部类等价于:
package inner; public class Parcel7b { class MyContents implements Contents{ private int i = 10; public int value(){ return i; } } public Contents contents(){ return new MyContents(); } public static void main(String[] args){ Parcel7b p = new Parcel7b(); Contents c = p.contents(); System.out.println(c.value()); } }
上面就是成员内部类
2.4、静态内部类static inner class
当内部类是static时,就是静态内部类
注意:
(1)要创建静态内部类的对象,并不需要其外部类的对象
(2)不能从内部类的对象中访问非静态的外部类对象
package inner; public class Outer {// 外部类 static String Label = "outer"; int size = 10; static class Inner{ // static 修饰 public void print(){ System.out.println(Label); } } public static void main(String[] args){ Outer.Inner inner = new Outer.Inner(); inner.print(); } }
3、为什么需要内部类?
内部类继承自某个类或实现某个接口,内部类的代码操作创建的外部类的对象,所以可以认为内部类提供了某种进入外部类的窗口
每个内部类都能独立底基础自一个接口的实现,所有无论外部类是否已经继承了某个接口的实现,对于内部类都是没有影响的
内部类允许继承多个抽象类
参考:《算法导论》---自己写的很差