匿名对象、匿名内部类、适配器模式

本文介绍了匿名对象的两种使用情况,包括匿名内部类实现接口、抽象类和具体类。重点讲解了匿名内部类在事件处理中的应用,如按钮的鼠标监听器,通过匿名内部类简化了接口方法的实现。同时,探讨了当接口方法众多时的不便,并引入适配器模式作为解决方案,以提高代码的灵活性和可维护性。

匿名对象2种使用情况:

    new Person().run(); //当对方法仅一次调用
    show(new Person());//作为实际参数传递

================================
匿名内部类:其实就是实现了接口、抽象、具体类中的子类而已。
匿名内部类的产生 :
传统编程模式:

class NoNameDemo
{
    public static void main(String args[]){
        WomenStar w=new WomenStar(); //步骤3:创建对象
        TuHao t=new TuHao();
        t.marry(w); 
    }
}

interface  WEB
{
    public void white();
}

//步骤1:实现接口
class WomenStar implements WEB    
{
    public void white(){
        System.out.println("女明星很白"); //步骤2:重写方法
    }
}

class TuHao 
{
    public void marry(WEB w){
        w.white();
    }
}

结果:
D:\java2>javac NoNameDemo.java
D:\java2>java NoNameDemo
女明星很白

有了匿名内部类之后的编程模式是:
实现接口、创建对象、重写方法3个步骤一气呵气

class NoNameDemo
{
    public static void main(String args[]){
        //WomenStar w=new WomenStar();
        TuHao t=new TuHao();
        t.marry(new WEB(){
            public void white(){
                System.out.println("匿名内部类改进后,女明星也很白!");
            }
        });//实现接口、重写方法、创建对象一气呵成
    }
}

interface  WEB
{
    public void white();
}

class WomenStar implements WEB
{
    public void white(){
        System.out.println("女明星很白");
    }
}

class TuHao 
{
    public void marry(WEB w){
        w.white();
    }
}

结果:
D:\java2>javac NoNameDemo.java
D:\java2>dir
NoNameDemo$1.class
NoNameDemo.class
NoNameDemo.java
TuHao.class
WEB.class
WomenStar.class
D:\java2>javap NoNameDemo$1
Compiled from "NoNameDemo.java"
final class NoNameDemo$1 extends java.lang.Object implements WEB{
    NoNameDemo$1();
    public void white();
}
D:\java2>java NoNameDemo
匿名内部类改进后,女明星也很白!

======================================

匿名内部类可以是针对接口、抽象类、具体类,前面是针对接口的内名内部类。
下面是针对抽象类的匿名内部类

class NoNameDemo
{
    public static void main(String args[]){
        Pet p=new Pet(){
            public void meng(){
                System.out.println("匿名内部类,宠物蒙蒙哒!");
            }
        };

        p.meng();
    }
}


abstract class Pet{
     abstract public void meng();
}

结果:
D:\java2>javac NoNameDemo.java
D:\java2>dir
NoNameDemo$1.class
NoNameDemo.class
NoNameDemo.java
Pet.class
D:\java2>javap NoNameDemo$1
Compiled from "NoNameDemo.java"
final class NoNameDemo$1 extends Pet{
    NoNameDemo$1();
    public void meng();
}
D:\java2>java NoNameDemo
匿名内部类,宠物蒙蒙哒!

class NoNameDemo
{
    public static void main(String args[]){
        Pet p=new Pet(){
            public void meng(){
                run();
                System.out.println("匿名内部类,宠物蒙蒙哒!");
            }

            public void run(){
                System.out.println("run...");
            }
        };

        p.meng();
    }
}

abstract class Pet{
     abstract public void meng();
}

结果:
D:\java2>javac NoNameDemo.java
D:\java2>java NoNameDemo
run...
匿名内部类,宠物蒙蒙哒!

注意:

class NoNameDemo
{
    public static void main(String args[]){
        Pet p=new Pet(){
            public void meng(){
                run();
                System.out.println("匿名内部类,宠物蒙蒙哒!");
            }

            public void run(){
                System.out.println("run...");
            }
        };

        p.meng();
        p.run(); //父类引用指向之类,因为父类没有该方法,所以编译报错
    }
}

abstract class Pet{
     abstract public void meng();
}

结果:
D:\java2>javac NoNameDemo.java
NoNameDemo.java:16: 找不到符号
符号: 方法 run()
位置: 类 Pet
                p.run();
                 ^
1 错误
class NoNameDemo
{
    public static void main(String args[]){
        Pet p=new Pet(){
            public void meng(){
                run();
                System.out.println("匿名内部类,宠物蒙蒙哒!");
            }

            public void run(){
                System.out.println("run...");
            }
        }.run();

        //p.meng();
        //p.run();
    }
}

abstract class Pet{
     abstract public void meng();
}

结果:
D:\java2>javac NoNameDemo.java
NoNameDemo.java:13: 不兼容的类型
找到: void
需要: Pet
                }.run();
                     ^
1 错误
class NoNameDemo
{
    public static void main(String args[]){
        /*Pet p=*/
        new Pet(){
            public void meng(){
                run();
                System.out.println("匿名内部类,宠物蒙蒙哒!");
            }

            public void run(){
                System.out.println("run...");
            }
        }.run();

        //p.meng();
        //p.run();
    }
}

abstract class Pet{
     abstract public void meng();
}

结果:
D:\java2>javac NoNameDemo.java
D:\java2>java NoNameDemo
run...

========================================
针对具体类的匿名内部类:

class NoNameDemo
{
    public static void main(String args[]){
        Pet p=new Dog(){
            public void run(){
                System.out.println("Dog run...");
            }
        };

        p.meng();
    }
}

abstract class Pet{
     abstract public void meng();
}

class Dog extends Pet
{
    public void meng(){
        System.out.println("Dog 萌萌哒!");
    }
}

结果:
D:\java2>javac NoNameDemo.java
D:\java2>dir
Dog.class
 NoNameDemo$1.class
 NoNameDemo.class
 NoNameDemo.java
 Pet.class
D:\java2>java NoNameDemo
Dog 萌萌哒!

=============================
匿名内部类按钮点击鼠标事件:
按钮、鼠标
按钮添加鼠标监听器,重写鼠标的单击、双击等方法
鼠标是接口,有单击、双击等方法
通过匿名内部类,实现按钮对象的单击、双击等事件

class NoNameDemo
{
    public static void main(String args[]){
        Button b=new Button();
        b.addListener(new MouseListener(){
            public void onClick(){
                System.out.println("鼠标单击");
            }

            public void dbClick(){
                System.out.println("鼠标双击");
            }
        });

        b.onClick();
        b.dbClick();
    }
}

class Button
{
    private MouseListener listener;
    public void addListener(MouseListener listener){
        this.listener=listener;

    }

    public void onClick(){
        listener.onClick();

    }
    public void dbClick(){
        listener.dbClick();
    }
}


//鼠标监听器
interface MouseListener
{
    public void onClick();
    public void dbClick();
}

结果:
D:\java2>javac NoNameDemo.java
D:\java2>java NoNameDemo
鼠标单击
鼠标双击

疑问:
如果鼠标接口的抽象方法很多,那么使用匿名内部类,按钮添加鼠标监听器,重写鼠标的方法就很多,这样很麻烦,那怎么办?

***-产生了设配器模式:***
步骤1:先使用一个抽象类实现鼠标接口,重写部分方法或者全部 实现(空实现、具体实现都可以),一般用空实现的比较多。
步骤2:在使用匿名内部类对象的时候,按钮添加鼠标监听器的时候只需要传入匿名内部类对象即实现鼠标接口的抽象类,并重写鼠标适配器抽象类没有实现的方法已经自己需要用到的方法。

===========================================
适配器的实现:


class NoNameDemo
{
    public static void main(String args[]){
        Button b=new Button();
        //按钮添加鼠标监听器,即鼠标适配器抽象类,该适配器空实现了鼠标接口的部分抽象方法,这里需要再次实现之前没有实现接口的方法或者自己有需要的方法。
        //步骤2:在使用匿名内部类对象的时候,按钮添加鼠标监听器的时候只需要传入匿名内部类对象即实现鼠标接口的抽象类鼠标适配器,并重写剩下的没有实现的方法以及自己需要的方法。
        b.addListener(new MouseAdapter(){
            public void onClick(){
                System.out.println("鼠标单击");
            }
            public void dbClick(){
                System.out.println("鼠标双击");
            }
        });

        b.onClick();
        b.dbClick();
    }
}

class Button
{
    private MouseListener listener;
    public void addListener(MouseListener listener){
        this.listener=listener;

    }

    public void onClick(){
        listener.onClick();

    }
    public void dbClick(){
        listener.dbClick();
    }
}


//鼠标监听器
interface MouseListener
{
    public void onClick();
    public void dbClick();
    public void rightClick();
    public void xxxClick();
}

//鼠标适配器,即实现鼠标接口的抽象类。空实现鼠标接口不需要使用到的方法或者全部空实现都是可以的。也可以具体实现,不过一般比较少这样用。

//步骤1:先使用一个抽象类实现鼠标接口,重写部分方法(空实现)
abstract class MouseAdapter implements MouseListener
{
    public  void rightClick(){};//空实现接口
    public  void xxxClick(){};
}

结果:
D:\java2>javac NoNameDemo.java
D:\java2>java NoNameDemo
鼠标单击
鼠标双击

==========================

class NoNameDemo
{
    public static void main(String args[]){
        Button b=new Button();
        b.addListener(new MouseAdapter(){
            public void onClick(){
            System.out.println("鼠标单击B");  
            }
        });

        b.onClick();//覆盖了鼠标适配器抽象类里的onClick方法,其实就是多态的体现,子类的方法会覆盖父类的方法
        b.dbClick();
    }
}

class Button
{
    private MouseListener listener;
    public void addListener(MouseListener listener){
        this.listener=listener;

    }

    public void onClick(){
        listener.onClick();

    }
    public void dbClick(){
        listener.dbClick();
    }
}


//鼠标监听器
interface MouseListener
{
    public void onClick();
    public void dbClick();
    public void rightClick();
    public void xxxClick();
}

//鼠标适配器
abstract class MouseAdapter implements MouseListener
{   
    public void onClick(){
        System.out.println("鼠标单击A");
    }
    public void dbClick(){}
    public  void rightClick(){}
    public  void xxxClick(){}
}

结果:
D:\java2>javac NoNameDemo.java
D:\java2>java NoNameDemo
鼠标单击B

=================================
链式编程:

class NoNameDemo
{
    public static void main(String args[]){
        Button b=new Button();
        b.addListener(new MouseAdapter(){
            public void onClick(){
                System.out.println("鼠标单击B");
            }

            public void dbClick(){
                System.out.println("鼠标双击");
            }
        });

        b.onClick();
        b.dbClick();


        new Button().addListener(new MouseAdapter(){
            public void onClick(){
                System.out.println("单击了匿名button!");
            }

            public void dbClick(){
                System.out.println("双击了匿名button!");
            }
        }).onClick().dbClick();//报错,addListener()返回空,onClick也返回空
    }
}

class Button
{
    private MouseListener listener;
    public void addListener(MouseListener listener){
        this.listener=listener;

    }

    public void onClick(){
        listener.onClick();

    }
    public void dbClick(){
        listener.dbClick();
    }
}


//鼠标监听器
interface MouseListener
{
    public void onClick();
    public void dbClick();
    public void rightClick();
    public void xxxClick();
}

//鼠标适配器
abstract class MouseAdapter implements MouseListener
{   
    public void onClick(){
        System.out.println("鼠标单击A");
    }
    public void dbClick(){}
    public  void rightClick(){}
    public  void xxxClick(){}
}

结果:
D:\java2>javac NoNameDemo.java
NoNameDemo.java:27: 无法取消引用 void
                }).onClick().dbClick();
                  ^
1 错误

改进后:

class NoNameDemo
{
    public static void main(String args[]){
        Button b=new Button();
        b.addListener(new MouseAdapter(){
            public void onClick(){
                System.out.println("鼠标单击B");
            }

            public void dbClick(){
                System.out.println("鼠标双击");
            }
        });

        b.onClick();
        b.dbClick();


        new Button().addListener(new MouseAdapter(){
            public void onClick(){
                System.out.println("单击了匿名button!");
            }

            public void dbClick(){
                System.out.println("双击了匿名button!");
            }
        }).onClick().dbClick();//链式编程
    }
}

class Button
{
    private MouseListener listener;
    public Button addListener(MouseListener listener){
        this.listener=listener;
        return this;//返回按钮对象

    }

    public Button onClick(){
        listener.onClick();
        return this;//返回按钮对象

    }
    public Button dbClick(){
        listener.dbClick();
        return  this;
    }
}


//鼠标监听器
interface MouseListener
{
    public void onClick();
    public void dbClick();
    public void rightClick();
    public void xxxClick();
}

//鼠标适配器
abstract class MouseAdapter implements MouseListener
{   
    public void onClick(){
        System.out.println("鼠标单击A");
    }
    public void dbClick(){}
    public  void rightClick(){}
    public  void xxxClick(){}
}

结果:
D:\java2>javac NoNameDemo.java
D:\java2>java NoNameDemo
鼠标单击B
鼠标双击
单击了匿名button!
双击了匿名button!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值