第10章:内部类(二)

版权声明:本文为博主原创文章,转载请注明出处。 https://blog.csdn.net/u013008179/article/details/79968602

匿名内部类

public interface Contents {
    int value();
}

public class Parcel7 {
    public Contents contents(){
        return new Contents() {
            private int i=11;
            public int value() {
                return i;
            }
        };
    }
    public static void main(String[] args) {
        Parcel7 p = new Parcel7();
        Contents contents = p.contents();
    }
}

contents()方法返回值的生成与表示这个返回值的类的定义结合在一起.另外,这个类是匿名的,它没有名字.更糟的是.看起来似乎是你要创建一个Contents 对象.但是然后(在到达语句结束的分号之前),你却说等一等,我想要在这里插入一个类的定义.
这种奇怪的语法指的是:创建一个继承Contents匿名类的对象.通过new表达式返回的引用被自动向上转型为Contents的引用.上述匿名内部类的语法是下述形式的简化形式.

public class Parcel7 {
    class MyContents implements Contents{
        private int i=11;
        public int value(){
            return i;
        }
    }
    public Contents contents(){
        return new MyContents();
    }
    public static void main(String[] args) {
        Parcel7 p = new Parcel7();
        Contents contents = p.contents();
    }
}
  • 在这个匿名内部类中,使用了默认的构造器来生成Contents.下面代码展示的是,如果你的基类需要一个有参数的构造器,应该怎么办
public class Parcel8 {
    public Wrapping wrapping(int x){
        return new Wrapping(x){
            public int value(){
                return super.value()*47;
            }
        };
    }

    public static void main(String[] args) {
        Parcel8 p = new Parcel8();
        Wrapping wrapping = p.wrapping(10);
    }
}

public class Wrapping {
    private int i;

    public Wrapping(int i) {
        this.i = i;
    }

    public int value() {
        return i;
    }
}

只需要传递合适的参数给基类的构造器即可,这里将x传进new Wrapping(x).尽管Warpping只是一个有具体实现的普通类,但它还是被其导出类当做公共接口来使用:
你会注意到,Wrapping 拥有一个要求传递一个参数的构造器,这使得事情变得更加有趣,在匿名内部类末尾的分号,并不是用来标记内部类结束的,实际上,它标记的是表达式的结束,只不过这个表达式正巧包含类匿名内部类罢了,因此,这与别的地方使用分号是一致的.

-匿名内部类定义字段事,还能够对其执行初始化操作

public class Parcel8 {
    public Destination destination(final String dest) {
        return new Destination() {
            private String label = dest;
            public String readLabel() {
                return label;
            }
        };
    }

    public static void main(String[] args) {
        Parcel8 p = new Parcel8();
        Destination dest = p.destination("Tasmania");
    }
}

匿名内部类,当它使用一个在其外部定义的对象时候,那么编译器会要求其引用的参数是final的,就像你在destination()的参数看到的那样,如果忘记了,将会得到编译时错误.

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页