Java中的内部类
在Java中,内部类是指在主要引入的类或接口内部声明的类,概括起来,与Java相同的逻辑相关类是纯面向对象的,因此更接近现实世界。现在,您一定想知道为什么要介绍它们?
与内部类相关的某些优点如下:
- 使代码干净易读。
- 可以访问外部类的私有方法,从而带来新的维度并使其更接近现实世界。
- 优化代码模块。
We do use them often as we go advance in java object-oriented programming where we want certain operations to be performed, granting access to limited classes and many more which will be clear as we do discuss and implement all types of inner classes in Java.
内部类的类型
Java中基本上有四种类型的内部类。
- 嵌套内部类
- 方法局部内部类
- 静态嵌套类
- 匿名内部类
让我们依次深入讨论上述每种类型以及一个干净的Java程序,这在每一步都非常关键,因为随着我们的坚持,它变得非常棘手。
类型 1:嵌套内部类
它可以访问外部类的任何私有实例变量。像任何其他实例变量一样,我们可以拥有访问修饰符 private、protected、public 和 default 修饰符。像类一样,接口也可以嵌套并且可以具有访问说明符。
示例 1A
Java
// Java Program to Demonstrate Nested class
// Class 1
// Helper classes
class Outer {
// Class 2
// Simple nested inner class
class Inner {
// show() method of inner class
public void show()
{
// Print statement
System.out.println("In a nested class method");
}
}
}
// Class 2
// Main class
class Main {
// Main driver method
public static void main(String[] args)
{
// Note how inner class object is created inside
// main()
Outer.Inner in = new Outer().new Inner();
// Calling show() method over above object created
in.show();
}
}
Java
// Java Program to Demonstrate Nested class
// Where Error is thrown
// Class 1
// Outer class
class Outer {
// Method defined inside outer class
void outerMethod()
{
// Print statement
System.out.println("inside outerMethod");
}
// Class 2
// Inner class
class Inner {
// Main driver method
public static void main(String[] args)
{
// Display message for better readability
System.out.println("inside inner class Method");
}
}
}
Java
// Java Program to Illustrate Inner class can be
// declared within a method of outer class
// Class 1
// Outer class
class Outer {
// Method inside outer class
void outerMethod()
{
// Print statement
System.out.println("inside outerMethod");
// Class 2
// Inner class
// It is local to outerMethod()
class Inner {
// Method defined inside inner class
void innerMethod()
{
// Print statement whenever inner class is
// called
System.out.println("inside innerMethod");
}
}
// Creating object of inner class
Inner y = new Inner();
// Calling over method defined inside it
y.innerMethod();
}
}
// Class 3
// Main class
class GFG {
// Main driver method
public static void main(String[] args)
{
// Creating object of outer class inside main()
// method
Outer x = new Outer();
// Calling over the same method
// as we did for inner class above
x.outerMethod();
}
}
Java
class Outer {
void outerMethod() {
int x = 98;
System.out.println("inside outerMethod");
class Inner {
void innerMethod() {
System.out.println("x= "+x);
}
}
Inner y = new Inner();
y.innerMethod();
}
}
class MethodLocalVariableDemo {
public static void main(String[] args) {
Outer x=new Outer();
x.outerMethod();
}
}
Java
class Outer {
void outerMethod() {
final int x=98;
System.out.println("inside outerMethod");
class Inner {
void innerMethod() {
System.out.println("x = "+x);
}
}
Inner y = new Inner();
y.innerMethod();
}
}
class MethodLocalVariableDemo {
public static void main(String[] args){
Outer x = new Outer();
x.outerMethod();
}
}
Java
// Java Program to Illustrate Static Nested Classes
// Importing required classes
import java.util.*;
// Class 1
// Outer class
class Outer {
// Method
private static void outerMethod()
{
// Print statement
System.out.println("inside outerMethod");
}
// Class 2
// Static inner class
static class Inner {
public static void display()
{
// Print statement
System.out.println("inside inner class Method");
// Calling method inside main() method
outerMethod();
}
}
}
// Class 3
// Main class
class GFG {
// Main driver method
public static void main(String args[])
{
Outer.Inner obj = new Outer.Inner();
// Calling method via above instance created
obj.display();
}
}
Java
// Java Program to Illustrate Anonymous Inner classes
// Declaration Without any Name
// As a subclass of the specified type
// Importing required classes
import java.util.*;
// Class 1
// Helper class
class Demo {
// Method of helper class
void show()
{
// Print statement
System.out.println(
"i am in show method of super class");
}
}
// Class 2
// Main class
class Flavor1Demo {
// An anonymous class with Demo as base class
static Demo d = new Demo() {
// Method 1
// show() method
void show()
{
// Calling method show() via super keyword
// which refers to parent class
super.show();
// Print statement
System.out.println("i am in Flavor1Demo class");
}
};
// Method 2
// Main driver method
public static void main(String[] args)
{
// Calling show() method inside main() method
d.show();
}
}
Java
// Java Program to Illustrate Anonymous Inner Classes
// Declaration Without Any Name
// As an implementer of Specified interface
// Interface
interface Hello {
// Method defined inside interface
void show();
}
// Main class
class GFG {
// Class implementing interface
static Hello h = new Hello() {
// Method 1
// show() method inside main class
public void show()
{
// Print statement
System.out.println("i am in anonymous class");
}
};
// Method 2
// Main driver method
public static void main(String[] args)
{
// Calling show() method inside main() method
h.show();
}
}
In a nested class method
Note: We can not have a static method in a nested inner class because an inner class is implicitly associated with an object of its outer class so it cannot define any static method for itself. For example, the following program doesn’t compile.
示例 1B
Java
// Java Program to Demonstrate Nested class
// Where Error is thrown
// Class 1
// Outer class
class Outer {
// Method defined inside outer class
void outerMethod()
{
// Print statement
System.out.println("inside outerMethod");
}
// Class 2
// Inner class
class Inner {
// Main driver method
public static void main(String[] args)
{
// Display message for better readability
System.out.println("inside inner class Method");
}
}
}
输出:
An interface can also be nested and nested interfaces have some interesting properties. We will be covering nested interfaces in the next post.
类型 2:方法本地内部类
内部类可以在外部类的方法中声明,我们将在下面的示例中说明,其中 Inner 是 outerMethod() 中的内部类。
示例 1
Java
// Java Program to Illustrate Inner class can be
// declared within a method of outer class
// Class 1
// Outer class
class Outer {
// Method inside outer class
void outerMethod()
{
// Print statement
System.out.println("inside outerMethod");
// Class 2
// Inner class
// It is local to outerMethod()
class Inner {
// Method defined inside inner class
void innerMethod()
{
// Print statement whenever inner class is
// called
System.out.println("inside innerMethod");
}
}
// Creating object of inner class
Inner y = new Inner();
// Calling over method defined inside it
y.innerMethod();
}
}
// Class 3
// Main class
class GFG {
// Main driver method
public static void main(String[] args)
{
// Creating object of outer class inside main()
// method
Outer x = new Outer();
// Calling over the same method
// as we did for inner class above
x.outerMethod();
}
}
inside outerMethod
inside innerMethod
方法局部内部类不能使用外部方法的局部变量,直到该局部变量未声明为最终变量。例如,以下代码会生成编译器错误。
Note: “x” is not final in outerMethod() and innerMethod() tries to access it.
示例 2
Java
class Outer {
void outerMethod() {
int x = 98;
System.out.println("inside outerMethod");
class Inner {
void innerMethod() {
System.out.println("x= "+x);
}
}
Inner y = new Inner();
y.innerMethod();
}
}
class MethodLocalVariableDemo {
public static void main(String[] args) {
Outer x=new Outer();
x.outerMethod();
}
}
inside outerMethod
x= 98
Note: Local inner class cannot access non-final local variable till JDK 1.7. Since JDK 1.8, it is possible to access the non-final local variable in method local inner class.
但是下面的代码编译并运行良好(注意这次 x 是最终的)
示例 3
Java
class Outer {
void outerMethod() {
final int x=98;
System.out.println("inside outerMethod");
class Inner {
void innerMethod() {
System.out.println("x = "+x);
}
}
Inner y = new Inner();
y.innerMethod();
}
}
class MethodLocalVariableDemo {
public static void main(String[] args){
Outer x = new Outer();
x.outerMethod();
}
}
inside outerMethod
x = 98
我们需要将局部变量声明为 final 的主要原因是局部变量一直在堆栈上,直到方法在堆栈上,但内部类的对象可能仍然存在于堆上。
方法本地内部类不能标记为私有、受保护、静态和瞬态,但可以标记为抽象和最终,但不能同时标记。
类型 3:静态嵌套类
静态嵌套类在技术上不是内部类。它们就像外部类的静态成员。
例子
Java
// Java Program to Illustrate Static Nested Classes
// Importing required classes
import java.util.*;
// Class 1
// Outer class
class Outer {
// Method
private static void outerMethod()
{
// Print statement
System.out.println("inside outerMethod");
}
// Class 2
// Static inner class
static class Inner {
public static void display()
{
// Print statement
System.out.println("inside inner class Method");
// Calling method inside main() method
outerMethod();
}
}
}
// Class 3
// Main class
class GFG {
// Main driver method
public static void main(String args[])
{
Outer.Inner obj = new Outer.Inner();
// Calling method via above instance created
obj.display();
}
}
inside inner class Method
inside outerMethod
类型 4:匿名内部类
匿名内部类的声明根本没有任何名称。它们以两种方式创建。
- 作为指定类型的子类
- 作为指定接口的实现者
方式一:作为指定类型的子类
例子:
Java
// Java Program to Illustrate Anonymous Inner classes
// Declaration Without any Name
// As a subclass of the specified type
// Importing required classes
import java.util.*;
// Class 1
// Helper class
class Demo {
// Method of helper class
void show()
{
// Print statement
System.out.println(
"i am in show method of super class");
}
}
// Class 2
// Main class
class Flavor1Demo {
// An anonymous class with Demo as base class
static Demo d = new Demo() {
// Method 1
// show() method
void show()
{
// Calling method show() via super keyword
// which refers to parent class
super.show();
// Print statement
System.out.println("i am in Flavor1Demo class");
}
};
// Method 2
// Main driver method
public static void main(String[] args)
{
// Calling show() method inside main() method
d.show();
}
}
i am in show method of super class
i am in Flavor1Demo class
在上面的代码中,我们有两个类 Demo 和 Flavor1Demo。这里 demo 充当超类,匿名类充当子类,两个类都有一个方法 show()。在匿名类 show() 方法被覆盖。
方式二:作为指定接口的实现者
例子:
Java
// Java Program to Illustrate Anonymous Inner Classes
// Declaration Without Any Name
// As an implementer of Specified interface
// Interface
interface Hello {
// Method defined inside interface
void show();
}
// Main class
class GFG {
// Class implementing interface
static Hello h = new Hello() {
// Method 1
// show() method inside main class
public void show()
{
// Print statement
System.out.println("i am in anonymous class");
}
};
// Method 2
// Main driver method
public static void main(String[] args)
{
// Calling show() method inside main() method
h.show();
}
}
i am in anonymous class
输出说明: