-
2021-03-09 06:35:27
匿名类是指没有类名的内部类,必须在创建时使用 new 语句来声明类。其语法形式如下:new()
{
//类的主体
};
这种形式的 new 语句声明一个新的匿名类,它对一个给定的类进行扩展,或者实现一个给定的接口。使用匿名类可使代码更加简洁、紧凑,模块化程度更高。
匿名类有两种实现方式:
1、继承一个类,重写其方法。
2、实现一个接口(可以是多个),实现其方法。
下面通过代码来说明。public class Out
{
void show()
{
System.out.println("调用 Out 类的 show() 方法");
}
}
public class TestAnonymousInterClass
{
//在这个方法中构造一个匿名内部类
private void show()
{
Out anonyInter=new Out()
{
//获取匿名内部类的实例
void show()
{
System.out.println("调用匿名类中的 show() 方法");
}
};
anonyInter.show();
}
public static void main(String[] args)
{
TestAnonymousInterClass test=new TestAnonymousInterClass();
test.show();
}
}
程序的输出结果如下:调用匿名类中的 show() 方法
从输出结果可以看出,匿名内部类有自己的实现。
提示:匿名内部类实现一个接口的方式与实现一个类的方式相同,这里不再赘述。
匿名类有如下特点。
(1) 匿名类和局部内部类一样,可以访问外部类的所有成员。如果匿名类位于一个方法中,则匿名类只能访问方法中 final 类型的局部变量和参数。public static void main(String[] args)
{
int a=10;
final int b=10;
Out anonyInter=new Out()
{
void show()
{
//System.out.println("调用了匿名类的 show() 方法"+a); //编译出错
System.out.println("调用了匿名类的 show() 方法"+b); //编译通过
}
};
anonyInter.show();
}
(2) 匿名类中允许使用非静态代码块进行成员初始化操作。Out anonyInter=new Out()
{
int i;
{ //非静态代码块
i=10; //成员初始化
}
public void show()
{
System.out.println("调用了匿名类的 show() 方法"+i);
}
};
(3) 匿名类的非静态代码块会在父类的构造方法之后被执行。
更多相关内容 -
Java的内部类和匿名类剖析
2021-01-21 17:12:49在那些修改中,引人注目的是内部类和匿名类。如运用得当,它们可使程序更易理解和维护。本文介绍内部类和匿名类在Java代码中是如何具体工作的,如何正确使用它们,以及如何避免一些常见的错误。 下面来看看这些特性... -
详细解读C++编程中的匿名类类型和位域
2020-09-02 21:05:50主要介绍了C++编程中的匿名类类型和位域,是C++入门学习中的基础知识,需要的朋友可以参考下 -
Java匿名类,匿名内部类实例分析
2020-08-19 08:21:00主要介绍了Java匿名类,匿名内部类,结合实例形式分析了Java匿名类,匿名内部类相关原理、用法及操作注意事项,需要的朋友可以参考下 -
Kotlin 匿名类实现接口和抽象类的区别详解
2020-08-19 12:46:03主要介绍了Kotlin 匿名类实现接口和抽象类的区别详解,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧 -
java 中使用匿名类直接new接口详解及实例代码
2020-08-31 04:29:25主要介绍了java 中使用匿名类直接new接口详解及实例代码的相关资料,需要的朋友可以参考下 -
Java 匿名类(匿名内部类)
2020-12-25 23:41:48Java匿名类(匿名内部类) 学习的参考博文:无恨之都 1. 初识 匿名类 标准说法: 内部类包括:成员类、局部类、匿名类(匿名内部类)。 匿名类概念: 匿名类可以使你的代码更加简洁 (JDK8之后Lambda更简洁)。 你可以...Java 匿名类(匿名内部类)
学习的参考博文:无恨之都
1. 初识 匿名类
标准说法: 内部类包括:成员类、局部类、匿名类(匿名内部类)。
匿名类概念:
- 匿名类可以使你的代码更加简洁 (JDK8之后Lambda更简洁)。
- 你可以定义一个类的同时对其进行实例化。
- 它与局部类很相似,不同的是它没有类名,如果某个局部类你只需要使用一次,就可以使用匿名类代替局部类。
- 匿名类是表达式,而非常规的类
匿名类的使用场景:
- 一个局部类只需要使用一次的时候
- 由于匿名类没有类名,那么除了定义它的地方,其他地方无法调用,所以匿名类也可以叫匿名内部类
2. 通过示例分析局部类和匿名类区别
sayHello
方法中有局部类和匿名类分别实现HelloWorld
接口的方法public class HelloWorldAnonymousClasses { interface HelloWorld { public void greet(); public void greetSomeone(String someone); } public void sayHello() { /** * 1、局部类:EnglishGreeting实现了HelloWorld接口 */ class EnglishGreeting implements HelloWorld { String name = "无参"; @Override public void greet() { greetSomeone(name); } @Override public void greetSomeone(String someone) { name = someone; System.out.println("局部类:" + name); } } // 创建局部类EnglishGreeting的实例化对象,使用接口类型接收 HelloWorld englishGreeting = new EnglishGreeting(); // 局部类:无参方法 englishGreeting.greet(); // 局部类:带参方法 englishGreeting.greetSomeone("带参"); /** * 2、匿名类实现HelloWorld接口并创建了实例化对象:frenchGreeting */ HelloWorld frenchGreeting = new HelloWorld() { String name = "无参"; @Override public void greet() { greetSomeone(name); } @Override public void greetSomeone(String someone) { name = someone; System.out.println("匿名类:" + name); } }; // 匿名类:无参方法 frenchGreeting.greet(); // 匿名类:带参方法 frenchGreeting.greetSomeone("带参"); } public static void main(String... args) { HelloWorldAnonymousClasses myApp = new HelloWorldAnonymousClasses(); myApp.sayHello(); }
【输出】
局部类:无参 局部类:带参 匿名类:无参 匿名类:带参
【分析】
代码里局部类和匿名类实现的功能是一样的,内部的方法实现的代码是也一样的,区别只在实现HelloWorld
接口的地方局部类的格式是:
- 创建局部类并且实现接口:
class EnglishGreeting implements HelloWorld {...}
- 创建局部类的实例化对象并用接口类型接收:
HelloWorld englishGreeting = new EnglishGreeting();
- 调用实例化对象的方法
匿名类的格式是:
- 创建匿名类实现接口同时对其进行实例化:
HelloWorld frenchGreeting = new HelloWorld() {...}
- 调用实例化对象的方法
【区别】
- 局部类
EnglishGreeting
实现HelloWorld
接口,有自己的类名:EnglishGreeting
,定义完成后需要再对其实例化对象:englishGreeting
才能可以使用方法 - 匿名类在定义时就已经实例化成对象:
frenchGreeting
,定义完了就可以直接使用方法 - 匿名类是一个表达式,因此在定义的最后用分号结束
3. 匿名内部类的语法
3.1 匿名类实现接口
其实上面的示例中的匿名类就是实现接口的方式,这个示例将实现更复杂的功能
public class InterfaceTest { public static void main(String[] args) { TomInterface tif = new TomInterface() { String name = "汤姆"; @Override public void getName() { System.out.println(name); } TomInterface setName(String name){ this.name = name; return this; } }.setName("杰瑞"); tif.getName(); } } interface TomInterface{ void getName(); }
【结果】
杰瑞
【分析】
main
方法创建匿名类实现TomInterface
接口并实例化:new TomInterface{...}
- 调用匿名类对象的
setName
方法,将杰瑞
赋值给匿名类的成员变量name
,并返回当前实例this
给接口变量tif
main
方法调用匿名类对象的方法tif.getName()
,而此时的匿名类的成员变量name
的值已经被替换成杰瑞
,所以最后输出杰瑞
而不是汤姆
3.2 匿名类继承父类 (匿名子类)
匿名类继承父类,调用父类构造,重写父类方法
public class ExtendTest { public static void main(String[] args) { String name = "李四"; // 创建父类对象,打印原始name值 PartherClass partherClass = new PartherClass(); System.out.println("父类的getName方法=" + partherClass.getName()); // 使用匿名类继承父类,并打印name值 PartherClass pc = new PartherClass(name){ @Override public String getName(){ return "匿名类 - "+super.getName(); } }; System.out.println(pc.getName()); } } class PartherClass{ private String name = "张三"; public PartherClass(){} public PartherClass(String name){ this.name = name; } public String getName(){ return this.name; } }
【结果】
父类的getName方法=张三 匿名类 - 李四
【分析】
- 创建父类对象并调用
getName
方法,这个不用细说 - 创建匿名类继承父类并实例化对象:
pc
,本次匿名类调用的是父类的带参构造,将参数赋值给了父类的name
- 调用匿名类重写的
getName
方法,得到新的name
值
3.3 区别
Demo demo = new Demo(xxx){...}
- 操作符:new
- 一个要实现的接口或要继承的类,示例3.1 是实现接口,示例3.2 是继承类
- 一对括号,如果是匿名子类,那么父类有构造参数就填,不带参就空着;如果匿名类是实现接口,那么括号里需要空着
{...}
,括号里括着的是匿名类的声明主体- 末尾的
;
号,因为匿名类的声明是一个表达式,是语句的一部分,所以需要分号结尾 - 表面上看匿名类没有类名,没有构造参数。但其实在编译的时候,编译器会给匿名类分配类名和构造器,只是我们无法操作也不能复用。如需验证,可以看编译后的class文件,多出一个命名格式:
匿名类定义类$?.class
的文件。例如示例3.2,匿名类的class文件就是:ExtendTest$1.class
-
匿名类/内部类/本地类 解读
2015-07-10 11:08:27详细对比测试了匿名类/内部类/本地类之间的区别,有例子+博客对比说明,希望对大家有所帮助 -
Java中的内部类和匿名类
2022-02-15 17:54:30Java中的内部类和匿名类是什么?到底怎么用?内部类
Java中的类有两种重要的成员,即成员变量和方法。其实Java还允许类有一种成员,即在一个类中声明另一个类,这就是内部类,而包含内部类的类叫做外嵌类。
内部类和外嵌类之间的关系如下:
1.内部类可以使用其外嵌类的成员变量和方法。
2.内部类中不可以声明类变量和类方法。
3.外嵌类可以使用内部类声明对象作为外嵌类的成员。
4.内部类仅供它的外嵌类使用,其他类不可以用某个类的内部类声明对象。
具体示例:class RedCowFarm{ //外嵌类 static String farmName; class RedCow{ //内部类开始 String cowName="红牛"; int height,weight; RedCow(int h,int w){ height=h; weight=w; } void speak(){ System.out.println("我是"+cowName+",身高:"+height+"cm,体重:"+weight+"kg,生活在"+farmName); } } // 内部类结束 RedCow cow=new RedCow(150,112); RedCowFarm(String s){ farmName=s; } } public class Test { public static void main(String[] args) { RedCowFarm redCowFarm=new RedCowFarm("红牛农场"); redCowFarm.cow.speak(); } }
内部类可以被修饰为static内部类,即上面的示例中可以将内部类声明为static class RedCow,类是一种数据类型,那么static内部类就是外嵌类中的一种静态数据类型,这样其它类就可以使用static内部类来声明创建对象了。
注意:static内部类不能操作外嵌类中的实例成员变量。
假如上面示例中内部类是static class RedCow的话,则可以作如下变动:
1.删除掉外嵌类的 RedCow cow=new RedCow(150,112); 对象声明和创建;
删除掉Test类main方法中的redCowFarm.cow.speak();
2.直接在Test类的main方法中添加以下代码也可以达到同样的运行效果:RedCowFarm.RedCow redCow=new RedCowFarm.RedCow(150,112); redCow.speak();
匿名类
一、和类有关的匿名类
1.我们可以直接使用一个类的子类的类体创建一个对象。在创建子类对象时,使用的是父类的构造方法和类体,这个类体被认为是子类去掉类声明之后的类体,称作匿名类。
2.匿名类主要是为了实现,要执行的任务或者方法需要一个对象,但是又不值得创建一个全新的对象。
3.匿名类可以继承,重写父类的方法,使用匿名类的时候,必然是在某个类当中直接使用匿名类创建对象,因此,匿名类一定是内部类。
4.由于匿名类是一个子类,但是没有类名,所以在使用匿名类创建对象时必须使用父类的构造方法。
5.匿名对象的引用可以传递给一个匹配的参数,匿名类常用的方式是向方法的参数传值。
具体示例:abstract class Speak{ public abstract void speakHello(); } class Student { void f(Speak sp){ sp.speakHello(); } } public class Test { public static void main(String[] args) { Speak speak; speak=new Speak() { //使用匿名类创建匿名对象,并且将匿名对象的引用传给父类声明的对象speak,可以理解为对象的上转型 @Override public void speakHello() { System.out.println("嗨喽"); } }; speak.speakHello(); Student student=new Student(); student.f(new Speak() { //使用匿名类创建匿名对象,并且将匿名对象的引用传递给匹配的参数 @Override public void speakHello() { System.out.println("hello"); } }); } }
二、和接口有关的匿名类
1.我们可以直接使用接口名和一个类体创建一个匿名对象,这个类体被称为是实现了这个接口的类去掉类声明后的类体,称为匿名类。
2.如果某个方法的参数是接口类型,那么可以使用接口名和类体组合创建一个匿名对象传递给这个方法的参数,但类体必须重写接口中的所有方法。
具体示例:interface Cubic{ double getCubic(double x); } class A{ void f(Cubic cu){ double result=cu.getCubic(3); System.out.println("result="+result); } } public class Test { public static void main(String[] args) { Cubic cubic=new Cubic() { //使用实现了接口的匿名类创建匿名对象,并且将对象的引用赋值给接口变量。 @Override public double getCubic(double x) { return x*x*x; } }; System.out.println(cubic.getCubic(5)); // 接口回调 A a=new A(); a.f(new Cubic() { //使用实现了接口的匿名类创建匿名对象,并且将对象的引用传递给匹配的参数 @Override public double getCubic(double x) { return x*x*x; } }); } }
既然都看完了,那就点个赞支持一下再走呗~ ~ 蟹蟹o
-
C++匿名类
2022-02-21 19:54:42java匿名类的C++实现一、java中的匿名类
java的观察者模式:
//观察者 public interface Observer{ public void update(); } //被观察主体 public class Subject{ private Array<Observer> observers; public void attach(Observer observer){ observers.add(observer); } public void notifyAllObservers(){ for (Observer observer : observers) { observer.update(); } } }
主函数
class Main{ public static void main(String[] args) { Subject subject = new Subject(); subject.attach(new Observer(){ private int state = 0;//状态 public void update(){ state++; System.out.println("当前状态为" + Integer.toString(state)); } }) } }
二、C++匿名类模仿实现
C++没有直接提供匿名类,但说到底,java匿名类主要解决问题如下:
1、保证依赖于接口提供方法的具体实现,从而保证解耦,使得添加的匿名类对同一接口能够有不同的行为。
2、提高可读性,因为添加的匿名类的方法实现就在附近,可以直接阅读,而无需跳到对应的类文件阅读。
3、保持简洁性,这是匿名性所带来的,因为没有命名一个具体的类占用命名空间,因此不会导致类的数目过多,而导致后期难以维护。C++虽然没有匿名类,但是有匿名对象和匿名函数,可以实现类似的效果。
#include<vector> #include<iostream> #include<memory> using namespace std; //观察者 class Observer { public: Observer(void (*doA)()) :doAction(doA) {} void (*doAction)();//函数指针 }; //被观察主体 class Subject { vector<Observer> observers; public: void attach(Observer observer) { observers.push_back(observer); } void notifyAllObservers() { for (auto it = observers.begin(); it != observers.end(); it++) { it->doAction(); } } }; int main() { Subject sj; sj.attach(Observer([] {static int state = 0; state++; cout << "匿名类1当前状态为"<<state<<endl; }));//匿名函数 sj.attach(Observer([] {static int state = 2; state++; cout << "匿名类2当前状态为"<<state<<endl; })); sj.notifyAllObservers(); }
这种方式虽然没有像java一样约定一个接口类,然后在用匿名类去实现接口方法,但也通过函数指针的方式,约定了函数名、函数的参数列表以及函数的返回值。
-
java 内部类(匿名类,匿名对象,静态内部类)详解及实例
2020-08-31 21:00:19主要介绍了java 内部类详解及实例代码的相关资料,需要的朋友可以参考下 -
Java 匿名类
2022-02-14 17:38:06匿名类是不能有名字的类,它们不能被引用,只能在创建时用 new 语句来声明它们。 使用匿名内部类我们必须要继承一个父类或者实现一个接口 匿名内部类中是不能定义构造函数的。 匿名内部类中不能存在任何的静态... -
java 内部类使用(内部匿名类)
2011-12-12 18:22:48java 成员内部类使用 内部匿名类 方法参数匿名类 方法匿名类 -
PHP7匿名类用法分析
2020-12-19 21:01:55匿名类跟匿名函数一样,创建一次性的简单对象 <?php /** * Created by PhpStorm. * User: bee * Date: 2016/4/24 * Time: 00:17 */ echo '匿名函数'; $anonymous_func = function(){return 'function';}; ... -
Java中匿名类的两种实现方式
2020-08-31 12:49:39本文主要介绍了Java中匿名类的两种实现方式。具有很好的参考价值,下面跟着小编一起来看下吧 -
简单谈谈java中匿名内部类构造函数
2020-09-03 04:50:50主要简单给我们介绍了java中匿名内部类构造函数,并附上了简单的示例,有需要的小伙伴可以参考下。 -
06-02 C# 匿名类
2021-02-02 11:40:10目录一、诞生二、普通类的实例化三、object匿名类1、优点2、缺点3、思考四、动态类型匿名类1、优点2、缺点3、思考五、弱类型(不确定类型)匿名类1、优点2、缺点3、思考4、使用场景六、本文代码 一、诞生 framework ... -
匿名类的定义,使用场景和使用方式
2021-05-24 12:37:25匿名内部类又叫匿名类,它有点像局部类(Local Class)或者内部类(Inner Class),只是匿名内部类没有名字,我们可以同时声明并实例化一个匿名内部类。 一个匿名内部类仅适用在想使用一个局部类并且只会使用这个局部类... -
Java中匿名子类 的 匿名对象、匿名子类 的 非匿名对象、非匿名类 的 匿名对象、非匿名类 的 非匿名对象
2020-11-18 15:07:47/** * @Author: YuShiwen * @Date: 2020/11/18 2:06 PM * @Version: 1.0 ... //非匿名类 的 非匿名对象,即类名为Freshman,对象名为:freshman Freshman freshman = new Freshman("Mr.Yu",18); -
匿名类的含义理解(多角度多案例通俗理解)
2021-08-06 10:59:28讲讲我对匿名类含义的理解,为什么要整出个匿名类来 文章目录核心一、案例一二、案例二总结 核心 匿名类的核心作用即:通过多态创造并使用一个父类的方法(如 一般的子类继承父类、抽象类、接口 里面的空方法) ... -
Java通过接口实现匿名类的实例代码
2020-09-04 23:08:22介绍了Java通过接口实现匿名类的实例代码,有需要的朋友可以参考一下 -
1.18 Java匿名类,匿名内部类
2020-09-30 13:12:36匿名类是指没有类名的内部类,必须在创建时使用 new 语句来声明类。其语法形式如下: new <类或接口>() { // 类的主体 }; 这种形式的 new 语句声明一个新的匿名类,它对一个给定的类进行扩展,或者实现一个... -
抽象类的介绍以及匿名类对象
2022-02-13 16:45:492.abstract修饰类:抽象类 此类不能实例化(创建对象\new对象) 抽象类中一定有构造器,便于子类对象实例化(创建对象\new对象)调用 开发中,都会提供抽象类的子类,让子类实例化,完成相关的操作 3.abstract修饰方法:抽象... -
6.2 匿名类
2019-07-20 17:22:11和类有关的匿名类 和接口有关的匿名类 一:和类有关的匿名类 Java允许用户直接使用一个类的子类的类体创建一个子类对象 在创建子类对象时,除了使用父类的构造方法外还有类体,此类体被认为是一个子类去掉类声明... -
PHP7匿名类的用法示例
2020-10-17 05:00:51主要介绍了PHP7匿名类的用法,结合实例形式分析了php7匿名类、匿名函数简单定义与使用技巧,需要的朋友可以参考下 -
使用内部和匿名类优化Java代码
2020-03-04 10:28:57Java 1.1通过对Java语言规范进行...在那些修改中,最引人注目的就是内部类和匿名类。如运用得当,它们可使程序更易理解和维护。本文来看看这些特性具体是如何工作的,如何正确使用它们,以及如何避免一些常见的错误。 -
ASP.NET中实现根据匿名类、datatable、sql生成实体类
2020-10-24 03:33:01主要介绍了ASP.NET中实现根据匿名类、datatable、sql生成实体类,这个小小工具类非常实用,使用起来也很方便,需要的朋友可以参考下 -
使用 Lambda 取代 Android 中的匿名类
2020-09-01 16:35:45本文主要介绍使用Lambda 取代 Android 中的匿名类的资料,这里这里了相关资料及简单示例代码帮助大家学习参考此部分的知识,有需要的小伙伴可以参考下