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

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:游动-白 设计师:我叫白小胖 返回首页
评论

打赏作者

雨少主

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值