首先说为什么有匿名类
两个原因(产生的使命)
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 父类的构造方法,实例化匿名类本身(因为没有名字嘛)
同理,引用也只能用父类的,所以一般是父类引用指向子类(匿名类)实例
原文:http://www.cnblogs.com/maxm/p/6763261.html