第三部分 内部类的特性
拥有对其所在的外围类所有元素的访问权限
java给予了内部类较大的访问权限,内部类最大的特点在于它能访问外部类的private成员
public class Outer {
private String tag;
public Outer(String tag) {
this.tag = tag;
}
public void getTag() {
System.out.println(tag);
}
class Inner {
public void f() {
//内部类方法访问外部类元素
System.out.println("Inner:"+tag);
getTag();
}
}
public static void main(String[] args){
Outer.Inner oi = new Outer("Outer.tag").new Inner();
oi.f();
}
}/*
Inner:Outer.tag
Outer.tag
2、匿名内部类和工厂方法
interface Book{void infoBook();}
interface BookFactory{Book getBook();}
class Math implements Book{
private double priceM = 29.80;
private String name = "Math";
public void infoBook(){
System.out.println(name+":"+priceM);
}
public static BookFactory factory = new BookFactory(){
//向上转型:类引用向上转型为接口引用
public Book getBook(){
return new Math();
}
};
}
class English implements Book{
private double priceE = 31.80;
private String name = "English";
public void infoBook(){
System.out.println(name+":"+priceE);
}
//实现接口的匿名内部类
public static BookFactory factory = new BookFactory(){
public Book getBook(){
return new English();
}
};
}
public class FactoryAndInner{
public static void getInfo(BookFactory factory){
Book theBook = factory.getBook();
theBook.infoBook();
}
public static void main(String[] args){
getInfo(Math.factory);
getInfo(English.factory);
}
}
建议:在编程时,优先使用类而不是接口,除非你的设计当中需要,并且必须要了解它
3、内部类的继承
内部类的构造器必须连接到指向其外围类对象的引用
a.该例中InheritInner将只继承内部类
----------
class WithInner{
class Inner{}
}
public class InheritInner extends WithInner.Inner{
InheritInner(WithInner wi){
wi.super();
}
public static void main(String[] args){
WithInner wi = new WithInner();
InheritInner ii = new InheritInner(wi);
}
}
----------
b.明确继承内部类
----------
class InnerExtends_2 {
public static void main(String[] args){
//构造器调用顺序:Outer2.Inner父类构造器->
//Outer2父类构造器->
//Outer1.Inner构造器->
//Outer2.Inner构造器
Outer1 ot = new Outer2();
//g()中将调用覆盖后的f()方法
ot.g();
}
}
class Outer1 {
protected class Inner {
public Inner() {System.out.println("Outer1.Inner");}
public void f() {System.out.println("Outer1.Inner.f()");}
}
private Inner in = new Inner();
public Outer1(){System.out.println("new Outer1");}
public void insertInner(Inner x){in = x;}
public void g(){in.f();}
}
class Outer2 extends Outer1{
public class Inner extends Outer1.Inner{
public Inner(){System.out.println("Outer2.Inner");}
//覆盖父类方法
public void f(){System.out.println("Outer2.Inner.f()");}
}
//insertInner方法允许Outer2.Inner向上转型为Outer1.Inner
public Outer2(){insertInner(new Inner());}
}
第四部分 嵌套类
普通内部类对象隐式地保存了指向创建它的外围对象的引用,如果将内部类声明为static,则不存在这个特殊的引用,此时称这个内部类为嵌套类
class Outer{
private int i = 0;
private static String s;
private static class Inner{
public void f(){
//只能访问外部类的静态成员
System.out.println(s);
}
}
public static Inner inner(){
return new Inner();
}
public static void main(String[] args){
//嵌套类创建对象不需要外部类对象
Inner in = inner();
}
}
----------
接口内部的类:一般接口当中不允许放置任何代码,但是嵌套类可以作为接口的一部分。任何放置到接口当中的类都自动地是public和static的
interface InterfaceInner {
void f();
//存在于接口内部的类
class Inner{
public void g(){}
}
Inner inner();
}
class Test implements InterfaceInner{
public void f(){}
public Inner inner(){
return new Inner();
}
public static void main(String[] args){
Inner in = new Test().inner();
}
}