首页 > 代码库 > 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 父类的构造方法,实例化匿名类本身(因为没有名字嘛)

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

 

 

    

    

Java匿名内部类使用与示例