📅  最后修改于: 2020-04-06 04:11:36             🧑  作者: Mango
内部类是指一个类,是另一个类的成员。在Java中,内部类基本上有四种类型。
1)嵌套内部类
2)方法局部内部类
3)匿名内部类
4)静态嵌套类
嵌套的内部类可以访问外部类的任何私有实例变量。像任何其他实例变量一样,我们可以将访问修饰符设置为private,protected,public和default修饰符。
像类一样,接口也可以嵌套并且可以具有访问说明符。
以下示例演示了一个嵌套类。
class Outer {
// 简单的嵌套内部类
class Inner {
public void show() {
System.out.println("一个嵌套类的方法");
}
}
}
class Main {
public static void main(String[] args) {
Outer.Inner in = new Outer().new Inner();
in.show();
}
}
输出:
一个嵌套类的方法
附带说明一下,我们不能在嵌套的内部类中使用静态方法,因为内部类与它的外部类的对象隐式关联,因此它不能为其自身定义任何静态方法。例如,以下程序无法编译。
class Outer {
void outerMethod() {
System.out.println("在outerMethod内");
}
class Inner {
public static void main(String[] args){
System.out.println("内部类方法");
}
}
}
输出:
Error illegal static declaration in inner class
Outer.Inner public static void main(String[] args)
modifier ‘static’ is only allowed in constant
variable declaration
接口也可以是嵌套的,并且嵌套接口具有一些有趣的属性。在下一篇文章中,我们将介绍嵌套接口。
方法局部内部类
内部类可以在外部类的方法中声明。在下面的示例中,Inner是externalMethod()中的内部类。
class Outer {
void outerMethod() {
System.out.println("在outerMethod内");
// 内部类是outerMethod()的
class Inner {
void innerMethod() {
System.out.println("在innerMethod内");
}
}
Inner y = new Inner();
y.innerMethod();
}
}
class MethodDemo {
public static void main(String[] args) {
Outer x = new Outer();
x.outerMethod();
}
}
输出
在outerMethod内
在innerMethod内
方法局部内部类不能使用外部方法的局部变量,除非该局部变量未声明为final。例如,以下代码生成编译器错误(请注意,x在externalMethod()中不是final,而innerMethod()尝试访问它)
class Outer {
void outerMethod() {
int x = 98;
System.out.println("在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();
}
}
输出:
local variable x is accessed from within inner class;
needs to be declared final
注意:局部内部类在JDK 1.7之前不能访问非最终局部变量。从JDK 1.8开始,可以在方法local内部类中访问非最终局部变量。但是下面的代码可以编译并正常运行(请注意,这次x是final的)
class Outer {
void outerMethod() {
final int x=98;
System.out.println("在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();
}
}
输出-:
在outerMethod内
X = 98
我们需要将局部变量声明为final的主要原因是,局部变量一直存在于堆栈上,直到方法在堆栈上为止,但是内部类的对象可能仍然存在于堆上。方法本地内部类不能标记为私有,受保护,静态和临时,但可以标记为抽象和最终,但不能同时标记为两者。
静态嵌套类
从技术上讲,静态嵌套类不是内部类。他们就像外部类的静态成员。
class Outer {
private static void outerMethod() {
System.out.println("在outerMethod内");
}
// 静态内部类
static class Inner {
public static void main(String[] args) {
System.out.println("内部类的方法");
outerMethod();
}
}
}
输出
内部类的方法
在outerMethod内
匿名内部类
声明的匿名内部类根本没有任何名称。它们以两种方式创建。
a)作为指定类型的子类
class Demo {
void show() {
System.out.println("父类的show方法");
}
}
class Flavor1Demo {
// An anonymous class with Demo as base class
static Demo d = new Demo() {
void show() {
super.show();
System.out.println("在Flavor1Demo类内");
}
};
public static void main(String[] args){
d.show();
}
}
输出
父类的show方法
在Flavor1Demo类内
在上面的代码中,我们有两个类Demo和Flavor1Demo。在这里,demo充当超类,匿名类充当子类,这两个类都具有show()方法。在匿名类中,show()方法被覆盖。
a)作为指定接口的实现者
class Flavor2Demo {
// An anonymous class that implements Hello interface
static Hello h = new Hello() {
public void show() {
System.out.println("i am in anonymous class");
}
};
public static void main(String[] args) {
h.show();
}
}
interface Hello {
void show();
}
输出:
i am in anonymous class
在上面的代码中,我们创建了一个匿名内部类的对象,但是这个匿名内部类是接口Hello的实现者。任何匿名内部类一次只能实现一个接口。它可以一次扩展一个类或实现一个接口。