zoukankan      html  css  js  c++  java
  • Java匿名内部类使用与示例

        首先说为什么有匿名类(产生的使命)

        两个原因

        1.简化代码编写

            某种情况下,类只需要扩展一个方法,没必要为了一个方法单独去写一个子类,然后然后调用子类,此时需要匿名类

        2.在不同的包内的类内调用类的protected方法(其实,也可以理解和第一个原因是一样的)

             匿名类继承了父类,并调用了父类的protected方法

        条件:

        匿名类完成上述使命,则需要继承一个类或者实现某个接口 

        形式:new <类或接口> <类的主体> 

        示例1:

    /**
     * 一般类
     * @author masan
     *
     */
    class Normal{
    	public void func(){
    		System.out.println("do with name");
    	}
    }
    
    public class UnNamedClass {
    	public static void main(String[] args) {
    		Normal m = new Normal(){
    			public void func(){
    				System.out.println("do without name");
    			};
    		};
    		m.func();
    	}
    }
    

      输出结果为:"do without name",

         匿名类继承了Normal类,并且覆盖了父类的func方法

         那么这个m到底是哪一个类的对象,是父类的还是子类的??

         示例2:

         

    /**
     * 一般类
     * @author masan
     *
     */
    class Normal{
    	
    	public void func(){
    		System.out.println("do with name");
    	}
    	
    }
    
    public class UnNamedClass {
    	
    	public static void main(String[] args) {
    		Normal m = new Normal(){
    // 覆盖了父类的方法func() public void func(){ System.out.println("do without name"); }; // 定义一个父类没有的方法func1 public void func1(){ System.out.println("func1 do without name"); } }; m.func(); // 输出 "do without name" m.func1(); // 报错,没有这个方法 // 调用func1(),这种写法是对的,可以调用匿名类的任意方法 new Normal(){ public void func(){ System.out.println("do without name"); }; public void func1(){ System.out.println("func1 do without name"); } }.func1(); // 上述示例说明这种关系是 父类引用指向了new出来的子类实例,m是父类的引用但是指向了子类的实例 } }

       上述示例说明这种关系是 父类引用指向了new出来的子类实例,那么接口的情况下会如何?

          示例3:匿名类实现接口

         

    // 先定义一个接口
    
    public interface Human {
    	public void eat();
    	
    	public void drink();
    
    }
    
    public class UnNamedClass {
    	
    	public static void main(String[] args) {
    		
    // 大家可以看到,这里new了一个接口,Java里接口是没有构造函数的,那么这里又是什么情况 Human masan = new Human(){ // 匿名类实现了Human接口的所有方法 @Override public void eat() { System.out.println(" masan eat "); } @Override public void drink() { System.out.println(" masan drink "); } }; masan.eat(); // 编译通过, 输出 " masan eat " masan.drink(); // 编译通过,输出 " masan drink "
    // 可以看出 masan这个对象可以调用所有实现了方法,也就是说其实masan是匿名类的实例,
    // 所以并没有实例化接口 而是实例化了这个匿名类 } }

      

     示例4:调用不同包的类的protected方法

    访问权限如果不熟悉的话,附上一张权限图

    修饰词

    本类

    同一个包的类

    继承类

    其他类

    private

    ×

    ×

    ×

    无(默认)

    ×

    ×

    protected

    ×

    public

     父类:(不同包)

    package another;
    
    public class Parent {
    	
    	public void run(){
    		System.out.println(" run with legs! ");
    	}
        
    	public void drink(){
    		System.out.println(" parent drink with mouth! ");
    	}
    	
            // protected  方法
    	protected void eat(){
    		System.out.println(" parent eat with mouth! (protected)");
    	}
    }
    

    另一个包调用protected方法

    package base;
    
    import another.Parent;
    
    
    public class UnNamedClass {
    	
    	public static void main(String[] args) {
    		
    		Parent p = new Parent();
    		
    		p.eat();  // 报错,因为不是同包内的类,也不是子类,所以,不能调用protected方法;
    		
    		//  假设只有这一个地方需要调用这个protected权限的eat()方法
    		//  则可以使用匿名类继承Parent,调用父类的eat
    		new Parent(){
    			// 匿名类新定义一个方法,方法体调用父类的eat();
    			public void peat(){
    			  super.eat();
    			};
    		}.peat();
    		
    		// 输出  " parent eat with mouth! (protected)" 则成功的调用了父类的eat()
    	}
    	
    }
    

    总结,综合上述4个示例可以看出:

    匿名类与普通类的区别主要在于,没有名字和使用时机

    匿名类的继承父类和实现接口都符合Java的一般规定

    匿名类在实例化的时候会有些特殊

    要new 父类的构造方法,实例化匿名类本身(因为没有名字嘛)

    同理,引用也只能用父类的,所以一般是父类引用指向子类(匿名类)实例

        

        

  • 相关阅读:
    2019总结
    数据挖掘-挖掘频繁模式、关联和相关性:基本概念和方法
    Elasticsearch-删除数据
    Elasticsearch-更新现有文档
    Elasticsearch-如何识别一篇文档
    2019-10-25 记录
    信息、数据、知识之间的关系
    螺旋式上升,螺旋形理论
    触发
    书籍阅读
  • 原文地址:https://www.cnblogs.com/maxm/p/6763261.html
Copyright © 2011-2022 走看看