Java中的匿名内部类
Java中的嵌套类是坚持了解匿名内部类之前的先决条件。它是一个没有名称的内部类,并且只为其创建了一个对象。匿名内部类在创建具有某些“附加”的对象实例时可能很有用,例如覆盖类或接口的方法,而不必实际子类化一个类。
Tip: Anonymous inner classes are useful in writing implementation classes for listener interfaces in graphics programming.
匿名类表达式的语法类似于构造函数的调用,不同之处在于代码块中包含类定义。
句法:
// Test can be interface,abstract/concrete class
Test t = new Test()
{
// data members and methods
public void test_method()
{
........
........
}
};
现在让我们来讨论一下常规类(普通类)和匿名内部类之间的区别
- 普通类可以实现任意数量的接口,但匿名内部类一次只能实现一个接口。
- 常规类可以扩展一个类并同时实现任意数量的接口。但是匿名内部类可以扩展一个类或可以实现一个接口,但不能同时实现两者。
- 对于常规/普通类,我们可以编写任意数量的构造函数,但我们不能为匿名内部类编写任何构造函数,因为匿名类没有任何名称,并且在定义构造函数时类名和构造函数名称必须相同。
访问封闭范围的局部变量,以及声明和访问匿名类的成员
和本地类一样,匿名类可以捕获变量;它们对封闭范围的局部变量具有相同的访问权限:
- 匿名类可以访问其封闭类的成员。
- 匿名类无法访问其封闭范围内未声明为 final 或有效 final 的局部变量。
- 与嵌套类一样,匿名类中的类型(例如变量)声明会隐藏封闭范围内具有相同名称的任何其他声明。
匿名类对其成员也有与本地类相同的限制:
- 我们不能在匿名类中声明静态初始化器或成员接口。
- 匿名类可以具有静态成员,前提是它们是常量变量。
Note: We can declare the following in anonymous classes as follows:
- Fields
- Extra methods (even if they do not implement any methods of the supertype)
- Instance initializers
- Local classes
方法:
匿名内部类是通用的,通过下面列出的两种方式创建:
- 类(可以是抽象的或具体的)
- 界面
现在让我们举一个例子来理解匿名内部类,让我们举一个简单的程序
例子
Java
// Java program to demonstrate Need for
// Anonymous Inner class
// Interface
interface Age {
// Defining variables and methods
int x = 21;
void getAge();
}
// Class 1
// Helper class implementing methods of Age Interface
class MyClass implements Age {
// Overriding getAge() method
@Override public void getAge()
{
// Print statement
System.out.print("Age is " + x);
}
}
// Class 2
// Main class
// AnonymousDemo
class GFG {
// Main driver method
public static void main(String[] args)
{
// Class 1 is implementation class of Age interface
MyClass obj = new MyClass();
// calling getage() method implemented at Class1
// inside main() method
obj.getAge();
}
}
Java
// Java Program to Demonstrate Anonymous inner class
// Interface
interface Age {
int x = 21;
void getAge();
}
// Main class
class AnonymousDemo {
// Main driver method
public static void main(String[] args)
{
// Myclass is hidden inner class of Age interface
// whose name is not written but an object to it
// is created.
Age oj1 = new Age() {
@Override public void getAge()
{
// printing age
System.out.print("Age is " + x);
}
};
oj1.getAge();
}
}
Java
// Java program to illustrate creating an immediate thread
// Using Anonymous Inner class that extends a Class
// Main class
class MyThread {
// Main driver method
public static void main(String[] args)
{
// Using Anonymous Inner class that extends a class
// Here a Thread class
Thread t = new Thread() {
// run() method for the thread
public void run()
{
// Print statement for child thread
// execution
System.out.println("Child Thread");
}
};
// Starting the thread
t.start();
// Displaying main thread only for readability
System.out.println("Main Thread");
}
}
Java
// Java program to illustrate defining a thread
// Using Anonymous Inner class that implements an interface
// Main class
class MyThread {
// Main driver method
public static void main(String[] args)
{
// Here we are using Anonymous Inner class
// that implements a interface i.e. Here Runnable
// interface
Runnable r = new Runnable() {
// run() method for the thread
public void run()
{
// Print statement when run() is invoked
System.out.println("Child Thread");
}
};
// Creating thread in main() using Thread class
Thread t = new Thread(r);
// Starting the thread using start() method
// which invokes run() method automatically
t.start();
// Print statement only
System.out.println("Main Thread");
}
}
Java
// Java program to illustrate defining a thread
// Using Anonymous Inner class that define inside argument
// Main class
class MyThread {
// Main driver method
public static void main(String[] args)
{
// Using Anonymous Inner class that define inside
// argument
// Here constructor argument
Thread t = new Thread(new Runnable() {
public void run()
{
System.out.println("Child Thread");
}
});
t.start();
System.out.println("Main Thread");
}
}
输出:
输出说明:
在上面的程序中,接口 Age 是用 getAge() 方法创建的,x=21。 Myclass 是作为 Age 接口的实现类编写的。正如在 Program 中所做的那样,无需编写单独的类 Myclass。而是直接将 Myclass 的代码复制到这个参数中,如下所示:
Age oj1 = new Age()
{
@Override
public void getAge()
{
System.out.print("Age is " + x);
}
};
Here, an object to Age is not created but an object of Myclass is created and copied in the entire class code as shown above. This is possible only with anonymous inner class. Such a class is called ‘anonymous inner class’, so here we call ‘Myclass’ as anonymous inner class.
例子:
Java
// Java Program to Demonstrate Anonymous inner class
// Interface
interface Age {
int x = 21;
void getAge();
}
// Main class
class AnonymousDemo {
// Main driver method
public static void main(String[] args)
{
// Myclass is hidden inner class of Age interface
// whose name is not written but an object to it
// is created.
Age oj1 = new Age() {
@Override public void getAge()
{
// printing age
System.out.print("Age is " + x);
}
};
oj1.getAge();
}
}
Age is 21
匿名内部类的类型
根据声明和行为,有 3 种匿名 Inner 类:
- 扩展类的匿名内部类
- 实现接口的匿名内部类
- 定义内部方法/构造函数参数的匿名内部类
类型 1:扩展类的匿名内部类
我们可以有一个扩展类的匿名内部类。例如,我们知道可以通过扩展 Thread 类来创建线程。假设我们需要一个即时线程,但我们不想一直创建一个扩展 Thread 类的类。借助这种类型的 Anonymous Inner 类,我们可以定义一个就绪线程。
例子
Java
// Java program to illustrate creating an immediate thread
// Using Anonymous Inner class that extends a Class
// Main class
class MyThread {
// Main driver method
public static void main(String[] args)
{
// Using Anonymous Inner class that extends a class
// Here a Thread class
Thread t = new Thread() {
// run() method for the thread
public void run()
{
// Print statement for child thread
// execution
System.out.println("Child Thread");
}
};
// Starting the thread
t.start();
// Displaying main thread only for readability
System.out.println("Main Thread");
}
}
Main Thread
Child Thread
类型 2:实现接口的匿名内部类
我们还可以有一个实现接口的匿名内部类。例如,我们也知道通过实现 Runnable 接口我们可以创建一个 Thread。这里我们使用一个实现接口的匿名 Inner 类。
例子
Java
// Java program to illustrate defining a thread
// Using Anonymous Inner class that implements an interface
// Main class
class MyThread {
// Main driver method
public static void main(String[] args)
{
// Here we are using Anonymous Inner class
// that implements a interface i.e. Here Runnable
// interface
Runnable r = new Runnable() {
// run() method for the thread
public void run()
{
// Print statement when run() is invoked
System.out.println("Child Thread");
}
};
// Creating thread in main() using Thread class
Thread t = new Thread(r);
// Starting the thread using start() method
// which invokes run() method automatically
t.start();
// Print statement only
System.out.println("Main Thread");
}
}
Main Thread
Child Thread
类型 3:定义内部方法/构造函数参数的匿名内部类
方法/构造函数参数中的匿名内部类通常用于图形用户界面 (GUI) 应用程序。为了让您熟悉语法,让我们看看下面的程序,它使用这种类型的匿名内部类创建线程
例子
Java
// Java program to illustrate defining a thread
// Using Anonymous Inner class that define inside argument
// Main class
class MyThread {
// Main driver method
public static void main(String[] args)
{
// Using Anonymous Inner class that define inside
// argument
// Here constructor argument
Thread t = new Thread(new Runnable() {
public void run()
{
System.out.println("Child Thread");
}
});
t.start();
System.out.println("Main Thread");
}
}
Main Thread
Child Thread