在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.
Types of Inner Classes
java中的内部类本质上有四种类型。
- 嵌套内部类
- 方法局部内部类
- 静态嵌套类
- 匿名内部类
让我们按顺序讨论以下每种类型in-depth 以及一个干净的 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();
}
}
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. But Since JAVA Version 16 we can have static members in our inner class also.
实施例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
方法局部内部类不能使用外部方法的局部变量,除非该局部变量未声明为 Final。例如,以下代码会生成编译器错误。
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的主要原因是,局部变量在方法入栈之前都存在于堆栈中,但可能存在内部类的对象仍然存在于堆上的情况。
方法局部内部类不能标记为 private、protected、static 和瞬态,但可以标记为 Abstract 和 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[])
{
// Calling method static display method rather than an instance of that class.
Outer.Inner.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。这里演示充当super-class,匿名类充当子类,两个类都有一个方法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
输出说明:
在上面的代码中,我们创建了一个匿名内部类的对象,但是这个匿名内部类是Hello接口的实现者。任何匿名内部类一次只能实现一个接口。它可以一次扩展一个类或实现一个接口。
解释
在Java中,内部类是在另一个类内部定义的类。内部类可以访问外部类的成员,包括私有成员,并且它可用于实现回调和事件处理程序。 Java中有四种类型的内部类:
成员内部类:它是在类的成员级别定义的非静态类。它可以访问外部类的所有成员,包括私有成员。
本地内部类:它是在方法或代码块内部定义的类。它可以访问定义它的方法或块的最终变量。
匿名内部类:是内联定义的、没有名称的类。它用于实现接口或扩展类,而无需创建单独的类。
静态嵌套类:它是在另一个类中定义的静态类。它无权访问外部类的非静态成员。
内部类有几个优点:
封装:内部类可以用来封装类的实现细节,使代码更加模块化和可维护。
访问控制:内部类可以访问外部类的私有成员,从而可以更精确地控制成员的可见性。
回调和事件处理程序:内部类可用于实现回调和事件处理程序,从而更轻松地处理图形用户接口中的事件。
代码组织:内部类可用于通过将相关类分组在一起来组织代码。
程序
Java
public class OuterClass {
private int outerVar;
public OuterClass(int var) {
outerVar = var;
}
public void outerMethod() {
System.out.println("This is an outer method");
}
// Inner class
public class InnerClass {
private int innerVar;
public InnerClass(int var) {
innerVar = var;
}
public void innerMethod() {
System.out.println("This is an inner method");
}
public void accessOuterVar() {
System.out.println("Outer variable from inner class: " + outerVar);
}
}
public static void main(String[] args) {
// Create an instance of the outer class
OuterClass outer = new OuterClass(10);
// Create an instance of the inner class
OuterClass.InnerClass inner = outer.new InnerClass(20);
// Access the inner class methods
inner.innerMethod();
inner.accessOuterVar();
}
}
This is an inner method Outer variable from inner class: 10
在此示例中,我们有一个外部类 OuterClass,它有一个内部类 InnerClass。内部类有自己的方法和变量,也可以访问外部类的方法和变量。
要创建内部类的实例,我们首先创建外部类的实例,然后用它来创建内部类。然后我们可以使用内部类的实例访问内部类的方法以及外部类的方法和变量。
在Java中使用内部类的好处是:
封装:内部类可以访问外部类的私有变量和方法。这有助于实现封装并提高代码可读性。
代码组织:内部类允许您将相关代码组合到一个位置。这使您的代码更易于理解和维护。
更好的访问控制:内部类可以声明为私有,这意味着它们只能在外部类内部访问。这提供了更好的访问控制并提高了代码安全性。
回调:内部类通常用于在事件驱动编程中实现回调。它们提供了一种在外部类的上下文中定义和实现回调函数的便捷方法。
多态性:可以使用内部类来实现多态性。您可以在外部类中定义类层次结构,然后创建实现不同子类的内部类的对象。
降低代码复杂性:内部类可以通过将复杂的逻辑和数据结构封装在外部类的上下文中来降低代码的复杂性。
总的来说,使用内部类可以产生更加模块化、可维护和灵活的代码。
相关用法
- Java Integer divideUnsigned()用法及代码示例
- Java Integer equals()用法及代码示例
- Java Integer getInteger()用法及代码示例
- Java Integer longValue()用法及代码示例
- Java Integer max()用法及代码示例
- Java Integer min()用法及代码示例
- Java Integer numberOfLeadingZeros()用法及代码示例
- Java Integer numberOfTrailingZeros()用法及代码示例
- Java Integer parseInt()用法及代码示例
- Java Integer parseUnsignedInt()用法及代码示例
- Java Integer remainderUnsigned()用法及代码示例
- Java Integer reverseBytes(int i)用法及代码示例
- Java Integer toBinaryString()用法及代码示例
- Java Integer toHexString()用法及代码示例
- Java Integer toUnsignedLong()用法及代码示例
- Java Integer toUnsignedString()用法及代码示例
- Java InputStream available()用法及代码示例
- Java InputStream close()用法及代码示例
- Java InputStream mark()用法及代码示例
- Java InputStream markSupported()用法及代码示例
- Java InputStream reset()用法及代码示例
- Java InputStream skip()用法及代码示例
- Java InputStreamReader close()用法及代码示例
- Java InputStreamReader getEncoding()用法及代码示例
- Java InputStreamReader ready()用法及代码示例
注:本文由纯净天空筛选整理自佚名大神的英文原创作品 Inner Class in Java。非经特殊声明,原始代码版权归原作者所有,本译文未经允许或授权,请勿转载或复制。