06_匿名内部类

【匿名内部类】

匿名内部类适合创建只需要一次使用的类。创建匿名内部类时会立即创建一个该类的实例,这个类的定义立即消失,匿名内部类不能重复使用。

【定义匿名内部类的格式】

new  实例接口() | 父类构造器(实参列表) {
    //匿名内部类的类体部分
}

从定义中可见,匿名内部类必须继承一个父类,或实现一个接口,但最多也只能实现一个接口或继承一个父类。

【匿名内部类的两条规则】

 1.匿名内部类不能是抽象类。

[ 原因 ]因为系统在创建匿名内部类的时候,会立即创建匿名内部类的对象。

2.匿名内部类不能定义构造方法。

[ 原因 ]由于匿名内部类没有类名,所以无法定义构造方法,但是匿名内部类可以定义初始化块,可以通过实例初始化块来完成构方法需要完成的事情。

【实例】

package com.Higgin.anonymous;

interface Product{
    public double getPrice();
    public String getName();
}

class AnonyMousDemo{
    public void printNameAndPrice(Product p){
        System.out.println(p.getName()+"------"+p.getPrice());
    }
}

public class AnonyMousTest {
    public static void main(String[] args) {
        AnonyMousDemo amd=new AnonyMousDemo();
        /**
         * 此处调用AnonyMousDemo的printNameAndPrice(p)方法。
         * 传入其匿名内部类的实例,定义匿名内部类无需class关键字,直接生产该匿名内部类的对象
     * 通过实现接口来创建匿名内部类时,匿名内部类无法显式创建构造方法,匿名内部类只有一个隐式的无参构造方法
*/ amd.printNameAndPrice(new Product(){ @Override public double getPrice(){ //匿名内部类中必须实现他的 抽象父类接口中 所有的抽象方法return 998.8; } @Override public String getName() { return "战斗机手机"
; } }); } }

【运行结果】

【分析】

AnonyMousDemo类的printNameAndPrice(Product p)方法需要传入一个Product的对象作为参数,但是Product是一个接口,无法直接创建对象,因此此处考虑的是创建一个Product接口的实现类的对象作为参数传入。(注意:如果这个Product接口的实现类只需使用一次,可以采用本例的方式;如果是Product的实现类需要多次使用,应该将该实现类定义成一个独立的类,方便多次使用)。

【区分单独定义情况(和上面作对比用)】

package com.Higgin.anonymous;

interface Product{
    public double getPrice();
    public String getName();
}

class ProductPhone implements Product{
    @Override
    public double getPrice(){
        return 998.8;
    }
    @Override
    public String getName() {
        return "战斗机手机";
    }
}

class AnonyMousDemo{
    public void printNameAndPrice(Product p){
        System.out.println(p.getName()+"------"+p.getPrice());
    }
}

public class AnonyMousTest {
    public static void main(String[] args) {
        AnonyMousDemo amd=new AnonyMousDemo();
        /**
         * 这里直接传入Product接口的实现类ProductPhone的对象
         */
        amd.printNameAndPrice(new  ProductPhone()); 
    }
}

【对比结论】

采用匿名内部类明显会简洁一些。

当通过实现接口来创建匿名内部类的时候,匿名内部类也不能显式创建构造方法,因此匿名内部类只能有一个隐式的构造方法,故"new 接口名()"的括号中不能传入参数值。

【如果通过继承父类来创建匿名内部类,匿名内部类将拥有和父类相似的构造器

package com.Higgin.anonymous;

/**
 *  抽象类Product(之前例子是接口) 
 */
abstract class Product{
    private String name;
    public abstract double getPrice();
    public Product(){}            //无参构造方法
    public Product(String name ){ //有参构造方法
        this.name=name;
    }
    //name的get方法
    public String getName() {
        return name;
    }
}


class AnonyMousDemo{
    public void printNameAndPrice(Product p){
        System.out.println(p.getName()+"------"+p.getPrice());
    }
}

public class AnonyMousTest {
    public static void main(String[] args) {
        AnonyMousDemo amd=new AnonyMousDemo();
        /**
         * 调用 有参构造方法,创建Product匿名实现类的对象
         */
        amd.printNameAndPrice(new Product("手机中的战斗机"){
            @Override
            public double getPrice() {  //实现其抽象方法
                return 998.8;
            }
        });
        System.out.println("---------------------我是飘过的分割线----------------------------");
        /**
         * 调用无参的构造方法,创建Product匿名实现类的对象
         */
        Product product=new Product(){
            //初始化块
            {
                System.out.println("===匿名内部类的初始化块===");
            }
            @Override
            public double getPrice() {  //实现其抽象方法
                return 889.9;
            }
            public String getName(){    //重写父类的实例方法getName  
                return "手机中的轰炸机";
            }
        };
        amd.printNameAndPrice(product);
        
    }
}    

【运行结果】

 

 【小结】

创建匿名内部类时,必须实现 接口或者抽象父类里的抽象方法,如果有需要也可以重写 父类中的普通方法

原文地址:https://www.cnblogs.com/HigginCui/p/6120694.html