在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。非經特殊聲明,原始代碼版權歸原作者所有,本譯文未經允許或授權,請勿轉載或複製。