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

两个原因

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

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

最新文章

  1. springboot 学习资源推荐
  2. iOS UINavigationController的使用
  3. Could not execute action
  4. mui jquery 同时使用
  5. [转载]Macaca 测试 Android 应用:UIAutomator
  6. oracle sqlserver mysql数据库分页
  7. Nginx: could not build the server_names_hash 解决办法
  8. 【Hadoop需要的Jar包】Hadoop编程-pom.xml文件
  9. SQL你必须知道的-函数及类型转换
  10. C++ 读取 pcap文件.
  11. 【转】VS 代码行数统计
  12. SRM 507(2-1000pt)
  13. OCP-1Z0-051-题目解析-第3题
  14. thin-provisioning-tools
  15. Directory Opus(DO) 个人使用经验 1.0
  16. python的Virtualenv
  17. Python 30分钟快速入门指南
  18. 【MySQL】InnoDB 内存管理机制 --- Buffer Pool
  19. January 20th, 2018 Week 3rd Saturday
  20. python测试开发django-39.xadmin详情页面布局form_layout

热门文章

  1. 3299: [USACO2011 Open]Corn Maze玉米迷宫
  2. 1856: [Scoi2010]字符串
  3. T——SQL基础语句(定义变量,赋值,取值,分支,循环,存储过程)
  4. SQLSERVER 切换数据库为单用户和多用户模式
  5. 000 Python之禅
  6. iOS开发之核心动画(Core Animation)
  7. jquery拖拽插件 tableDnD
  8. oracle索引(转)
  9. 关于开发环境中的消息在download时没有下载下来时的问题
  10. [认证授权] 2.OAuth2(续) &amp; JSON Web Token