zoukankan      html  css  js  c++  java
  • 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);
            
        }
    }    

    【运行结果】

     

     【小结】

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

  • 相关阅读:
    递归程序设计方法
    深入理解 Entity Framework
    面向对象设计的七大原则分析与实践
    JavaScript内置对象与原型继承
    设计模式之创建型(1)-简单工厂
    设计模式之创建型(2)-工厂方法模式
    设计模式之创建型(3)-抽象工厂模式
    设计模式之创建型(4)-建造者模式(Builder)
    设计模式之创建型(5)-单例模式(Singleton)
    设计模式之创建型(6)-原型模式(Prototype)
  • 原文地址:https://www.cnblogs.com/HigginCui/p/6120694.html
Copyright © 2011-2022 走看看