欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 房产 > 建筑 > Java内部类一口气讲完!( •̀ ω •́ )✧

Java内部类一口气讲完!( •̀ ω •́ )✧

2025/3/10 6:04:00 来源:https://blog.csdn.net/m0_69824302/article/details/142410102  浏览:    关键词:Java内部类一口气讲完!( •̀ ω •́ )✧

Java 内部类

Java面向对象的设计 - Java 内部类

什么是内部类?

作为包的成员的类被称为顶级类。

一个类可以在另一个类中声明。这种类型的类称为内部类。

如果在另一个类中声明的类被显式或隐式声明为static,它被称为嵌套类,而不是内部类。

包含内部类的类称为封闭类或外部类。

例子

下面的代码声明一个内部类。

class Outer {public class Inner {// Members of the Inner class go here}// Other members of the Outer class go here
}

Outer类是一个顶级类。

Inner类是一个内部类。它是外类的成员。

外层类是Inner类的封闭(外部)类。

内部类可以是另一个内部类的封闭类。内部类的嵌套层次没有限制。

内部类的实例只能存在于其封闭类的实例中。

使用内部类的优点

以下是内部类的一些优点。

  • 在将使用它们的其他类附近定义类。
  • 提供了一个额外的命名空间来管理类结构。
  • 一些设计模式使用内部类更容易实现。
  • 实现回调机制使用内部类是优雅和方便的。它有助于在Java中实现闭包。

访问局部变量的限制

下面的代码演示了访问局部内部类中的局部变量的规则。

main()方法声明两个局部变量x和y。这两个变量都是最终的。

变量x在被初始化之后从不改变,变量y不能被改变,因为它被声明为final。

public class Main {public static void main(String... args) {int x = 1;final int y = 2;class LocalInner {void print() {System.out.println("x = " + x);System.out.println("y = " + y);}}/** Uncomment the following statement will make the variable x no longer* an effectively final variable and the LocalIneer class will not compile.*/// x = 100;LocalInner li = new LocalInner();li.print();}
}

上面的代码生成以下结果。

内部类和继承

内部类可以继承另一个内部类,顶级类或其封闭类。

class A {public class B {}public class C extends B {}public class D extends A {}
}class E extends A {public class F extends B {}
}

内部类中没有静态成员

Java中的关键字static使一个构造成为一个顶层结构。

因此,我们不能为内部类声明任何静态成员(字段,方法或初始化器)。

允许在内部类中有作为编译时常量的静态字段。

class A {public class B {public final static int DAYS_IN_A_WEEK = 7; // OKpublic final String str = new String("Hello");}
}

生成的内部类的类文件

每个内部类都被编译成一个单独的类文件。

成员内部类和静态内部类的类文件名格式如下:

<outer-class-name>$<member-or-static-inner-class-name>

局部内部类的类文件名的格式如下:

<outer-class-name>$<a-number><local-inner-class-name>

匿名类的类文件名的格式如下:

<outer-class-name>$<a-number>

类文件名中的<a-number>是从1开始顺序生成的数字,以避免任何名称冲突。

静态上下文中的内类

我们可以在静态上下文中定义一个内部类,例如静态方法或静态初始化器。

所有静态字段成员都可以访问这样的内部类。

class Outer {static int k = 1;int m = 2;public static void staticMethod() {// Class Inner is defined in a static contextclass Inner {int j = k; // OK. Referencing static field k// int n = m; // An error. Referencing non-static field m}}
}

Java 内部类类型

Java面向对象设计 - Java内部类类型

您可以在类中的任何位置定义内部类,您可以在其中编写Java语句。

有三种类型的内部类。内部类的类型取决于位置和声明的方式。

  • 成员内部类
  • 局部内部类
  • 匿名内部类

成员内部类

成员内部类在类中声明的方式与声明成员字段或成员方法相同。

它可以声明为public,private,protected或package-level。

成员内部类的实例可以仅存在于其封闭类的实例内。

以下代码创建了一个成员内部类。

class Car {private int year;// A member inner class named Tire publicclass Tire {private double radius;public Tire(double radius) {this.radius = radius;}public double getRadius() {return radius;}} // Member inner class declaration ends here// A constructor for the Car classpublic Car(int year) {this.year = year;}public int getYear() {return year;}
}

局部内部类

一个局部内部类在块中声明。其范围仅限于声明它的块。

由于其范围限于其封闭块,因此其声明不能使用任何访问修饰符,例如public,private或protected。

通常,在方法内定义局部内部类。但是,它也可以在静态初始化器,非静态初始化器和构造器中定义。

下面的代码显示了一个局部内部类的例子。

import java.util.ArrayList;
import java.util.Iterator;public class Main {public static void main(String[] args) {StringList tl = new StringList();tl.addTitle("A");tl.addTitle("B");Iterator iterator = tl.titleIterator();while (iterator.hasNext()) {System.out.println(iterator.next());}}
}
class StringList {private ArrayList<String> titleList = new ArrayList<>();public void addTitle(String title) {titleList.add(title);}public void removeTitle(String title) {titleList.remove(title);}public Iterator<String> titleIterator() {// A local inner class - TitleIteratorclass TitleIterator implements Iterator<String> {int count = 0;@Overridepublic boolean hasNext() {return (count < titleList.size());}@Overridepublic String next() {return titleList.get(count++);}}TitleIterator titleIterator = new TitleIterator();return titleIterator;}
}

上面的代码生成以下结果。

例子

下面的代码有一个局部内部类继承自另一个公共类。

import java.util.Random;abstract class IntGenerator {public abstract int getValue() ;
}
class LocalGen {public IntGenerator getRandomInteger() {class RandomIntegerLocal extends IntGenerator {@Overridepublic int getValue() {Random rand = new Random();long n1 = rand.nextInt();long n2 = rand.nextInt();int value = (int) ((n1 + n2) / 2);return value;}}return new RandomIntegerLocal();} // End of getRandomInteger() method
}public class Main {public static void main(String[] args) {LocalGen local = new LocalGen();IntGenerator rLocal = local.getRandomInteger();System.out.println(rLocal.getValue());System.out.println(rLocal.getValue());}
}

上面的代码生成以下结果。

匿名内部类

匿名内部类没有名称。因为它没有名称,它不能有一个构造函数。

匿名类是一次性类。您定义一个匿名类并同时创建它的对象。

创建匿名类及其对象的一般语法如下:

new Interface()  {
// Anonymous  class body  goes  here
}

new Superclass(<argument-list-for-a-superclass-constructor>)  {
// Anonymous  class body  goes  here
}

new运算符用于创建匿名类的实例。

它后面是现有的接口名称或现有的类名称。

接口名称或类名称不是新创建的匿名类的名称。

如果使用接口名称,则匿名类实现接口。

如果使用类名,则匿名类继承自类。

仅当新运算符后面跟有类名时,才使用<argument-list>。如果新运算符后跟接口名称,则它为空。

如果<argument-list>存在,它包含要调用的现有类的构造函数的实际参数列表。

匿名类主体像往常一样在大括号中。

匿名类主体应该简短,以便更好的可读性。

下面的代码包含一个简单的匿名类,它在标准输出上打印一条消息。

public class Main {public static void main(String[] args) {new Object() {// An instance initializer{System.out.println("Hello from  an  anonymous class.");}}; // A semi-colon is necessary to end the statement}
}

上面的代码生成以下结果。

例2

以下代码使用匿名类来创建Iterator。

import java.util.ArrayList;
import java.util.Iterator;public class Main {private ArrayList<String> titleList = new ArrayList<>();public void addTitle(String title) {titleList.add(title);}public void removeTitle(String title) {titleList.remove(title);}public Iterator<String> titleIterator() {// An anonymous classIterator<String> iterator = new Iterator<String>() {int count = 0;@Overridepublic boolean hasNext() {return (count < titleList.size());}@Overridepublic String next() {return titleList.get(count++);}}; // Anonymous inner class ends herereturn iterator;}
}

Java 静态对象类

Java面向对象设计 - Java静态内部类

静态成员类不是内部类

在另一个类的主体中定义的成员类可以声明为静态。

例子

以下代码声明了顶级类A和静态成员类B:

class A {// Static member classpublic static class B {// Body for class B goes here}
}

注意

静态成员类不是内部类。它被认为是一个顶级类。

静态成员类也称为嵌套顶级类。

A类的实例和B类的实例可以独立存在,因为它们都是顶级类。

静态成员类可以声明为public,protected,package-level或private,以限制其在其封闭类之外的可访问性。

使用静态成员类有两个好处:

  • 静态成员类可以访问其包含类的静态成员,包括私有静态成员。
  • 一个包通过提供一个命名空间,就像一个顶级类的容器。具有静态成员类的顶级类提​​供了额外的命名空间层。

静态成员类是其封闭顶级类的直接成员,而不是包的成员。

静态成员类的对象的创建方式与使用new运算符创建顶级类的对象的方式相同。要创建一个B类的对象,你写

A.B bReference = new A.B();

由于类B的简单名称在类A中的范围内,因此我们可以使用其简单名称在类A中创建其对象

B  bReference2 = new B(); // This  statement appears inside class  A  code

我们还可以通过导入com.java2s.innerclasses.A.B类,使用A类之外的简单名称B.

例2

下面的代码显示了如何使用静态内部类。

public class Main {public static void main(String[] args) {Car.Tire m = new Car.Tire(17);Car.Tire m2 = new Car.Tire(19);Car.Keyboard k = new Car.Keyboard(122);Car.Keyboard k1 = new Car.Keyboard(142);System.out.println(m);System.out.println(m2);System.out.println(k);System.out.println(k1);}
}
class Car {// Static member class - Monitorpublic static class Tire {private int size;public Tire(int size) {this.size = size;}public String toString() {return "Monitor   - Size:" + this.size + "  inch";}}// Static member class - Keyboardpublic static class Keyboard {private int keys;public Keyboard(int keys) {this.keys = keys;}public String toString() {return "Keyboard  - Keys:" + this.keys;}}
}

上面的代码生成以下结果。

Java 内部类对象 

Java面向对象设计 - Java内部类对象

局部内部类的对象是使用块中的新运算符创建的,它声明了类。

在声明类的同时创建一个匿名类的对象。

静态成员类是另一种类型的顶级类。

您可以按照创建顶级类的对象的方式创建静态成员类的对象。

成员内部类的实例始终存在于其封闭类的实例中。

语法

创建成员内部类的实例的一般语法如下:

OuterClassReference.new MemberInnerClassConstructor()

OuterClassReference是包围类的引用,后跟一个后跟新运算符的点。

例子

成员内部类的构造函数调用遵循new运算符。

class Outer  {public class  Inner {}
}

要创建内部成员内部类的实例,必须首先创建其封闭类Outer的实例。

Outer  out  = new Outer();

现在,您需要在out参考变量上使用new运算符来创建Inner类的对象。

out.new Inner();

为了将内部成员内部类的实例的引用存储在引用变量中,我们可以写下面的语句:

Outer.Inner in = out.new   Inner();

以下代码显示了如何创建成员内部类的对象

public class Main {public static void main(String[] args) {Car c = new Car();Car.Tire t = c.new Tire(9);}
}
class Car {public class Tire {private int size;public Tire(int size) {this.size = size;}public String toString() {return "Monitor   - Size:" + this.size + "  inch";}}}

Java 内部类成员

Java面向对象设计 - Java内部类成员

内部类可以访问其所有实例成员,实例字段和其封闭类的实例方法。

class Outer {private int value = 2014;public class Inner {public void printValue() {System.out.println("Inner: Value  = " + value);}} // Inner class ends herepublic void printValue() {System.out.println("Outer: Value  = " + value);}public void setValue(int newValue) {this.value = newValue;}
}public class Main {public static void main(String[] args) {Outer out = new Outer();Outer.Inner in = out.new Inner();out.printValue();in.printValue();out.setValue(2015);out.printValue();in.printValue();}
}

上面的代码生成以下结果。

例子

以下代码显示如何访问内部类的内部变量。

public class Main {public static void main(String[] args) {Outer out = new Outer();Outer.Inner in = out.new Inner();out.printValue();in.printValue();out.setValue(3);out.printValue();in.printValue();}
}
class Outer {private int value = 1;public class Inner {private int value = 2;public void printValue() {System.out.println("Inner: Value  = " + value);}} // Inner class ends herepublic void printValue() {System.out.println("Outer: Value  = " + value);}public void setValue(int newValue) {this.value = newValue;}
}

上面的代码生成以下结果。

在内部类中使用关键字this

以下代码显示如何在内部类中使用关键字this。

class Outer {private int value = 1;class QualifiedThis {private int value = 2;public void printValue() {System.out.println("value=" + value);System.out.println("this.value=" + this.value);System.out.println("QualifiedThis.this.value=" + QualifiedThis.this.value);}public void printHiddenValue() {int value = 2;System.out.println("value=" + value);System.out.println("this.value=" + this.value);System.out.println("QualifiedThis.this.value=" + QualifiedThis.this.value);}}public void printValue() {System.out.println("value=" + value);System.out.println("this.value=" + this.value);}  
}public class Main {public static void main(String[] args) {Outer outer = new Outer();Outer.QualifiedThis qt = outer.new QualifiedThis();System.out.println("printValue():");qt.printValue();System.out.println("printHiddenValue():");qt.printHiddenValue();outer.printValue();}
}

上面的代码生成以下结果。

隐藏变量

如果实例变量名称被隐藏,您必须使用关键字this或类名称以及关键字this限定其名称。

class TopLevelOuter {private int v1 = 100;// Here, only v1 is in scopepublic class InnerLevelOne {private int v2 = 200;// Here, only v1 and v2 are in scopepublic class InnerLevelTwo {private int v3 = 300;// Here, only v1, v2, and v3 are in scopepublic class InnerLevelThree {private int v4 = 400;// Here, all v1, v2, v3, and v4 are in scope}}}
}

从外部类引用变量

以下代码显示如何从外部类引用变量。

public class Test{private int value = 1;public class Inner {private int value = 2;public void printValue() {System.out.println("Inner: Value  = " + value);System.out.println("Outer: Value  = " + Test.this.value);}} // Inner class ends herepublic void printValue() {System.out.println("\nOuter - printValue()...");System.out.println("Outer: Value  = " + value);}public void setValue(int newValue) {System.out.println("\nSetting  Outer"s value to " + newValue);this.value = newValue;}}

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词