一、什么是内部类?
内部类就是将一个类定义在另一个类中。
class Outer{
//内部类
class Inner{
}
}
二、内部类的分类
内部类分为两类:成员内部类(静态和非静态)和局部内部类(方法内,代码块内,构造器内)
class Outer {
//静态成员内部类
static class StaticInner {
}
//非静态内部类
class Inner {
}
//方法
public void method() {
//局部内部类
class MethodInner {
}
}
//非静态代码块
{
//局部内部类
class BlockInner {
}
}
//静态代码块
static{
//局部内部类
class BlockInner {
}
}
//构造器
public Outer() {
//局部内部类
class ConstructorInner {
}
}
}
2.1 成员内部类
成员内部类作为外部类的成员,那么可以调用外部类的结构,可以被static修饰,
可以被4种不同的权限修饰符修饰。
作为一个类,那么它必然有着作为类的一切可以做的,包括了类内可以定义的各种东西(属性,方法,构造器等,对于可以被static修饰的属性,方法,只能当成员内部类被static修饰时才有效),可以被final修饰,可以被abstract修饰。
class Outer {
private String outerName;
static int outerAge;
public void outerMethod(){
}
class Inner {
String name;
final int age=1;
//static int id=1; //Inner classes cannot have static declarations
public Inner(String name) {
this.name = name;
}
public void method(){
Outer.this.outerMethod();
//等价于
outerMethod();//相当于省略了Outer.this.
Outer.this.outerName="Inner";//可以省略了Outer.this.
Outer.outerAge=10;
System.out.println("我是方法");
}
public final void finalMethod(){
System.out.println("我是final方法");
}
//Inner classes cannot have static declarations
//public static void staticMethod(){
//}
}
private class InnerPrivate {
}
public class InnerPublic {
}
protected class InnerProtected {
}
final class InnerFinal {
}
static class StaticInner {
String name;
static String country="china";
final int ID=10;
public StaticInner(String name) {
this.name = name;
}
public void method(){
System.out.println("我是方法");
}
public static void staticMethod(){
System.out.println("我是静态方法");
}
public final void finalMethod(){
System.out.println("我是final方法");
}
}
}
在类中调用本类中的属性和方法通过this调用,那么在内部类中如何调用外部类中的属性和方法呢?在上例中,Outer.this.outerName="Inner";
和Outer.this.outerMethod()
的形式来调用外部类中的属性和方法,即外部类名.this.属性或外部类名.this.方法,外部类名.this所代表的含义就是外部类对象的引用。当前外部类属性和内部类属性并不重名,那么如果重名该如何区分呢?
class Outer{
String name="outer";
class Inner{
String name="inner";
public void method(String name){
System.out.println(name);//形参
System.out.println(this.name);//Inner的name属性
System.out.println(Outer.this.name);//Outer的name属性
}
}
}
public class Demo{
public static void main(String[] args) {
Outer.Inner inner=new Outer().new Inner();
inner.method("method");
}
}
输出:
method
inner
outer
public class Demo {
public static void main(String[] args) {
Outer outer=new Outer();
Outer.Inner inner = outer.new Inner("hh");
inner.method();
System.out.println("=======================================");
Outer.StaticInner staticInner=new Outer.StaticInner("hh");
staticInner.method();
}
}
输出:
我是方法
=======================================
我是方法
上例中,对于非静态内部类,我们通过使用外部类的对象来创建内部类的对象(如:outer.new Inner("hh");
,)来进行实例化内部类。为什么要如此?
在拥有外部类对象之前是不可能创建内部类对象的。这是因为内部类对象会暗暗地连接到建它的外部类对象上。
上述来自《Java编程思想》
对于静态内部类,我们则不需要外部类的对象了。直接通过new 外部类名.静态内部类名的方式(如:new Outer.StaticInner("hh");
)
2.2 局部内部类
在上面我们知道了,局部内部类可以定义在代码块,构造器,方法中。
使用局部内部类,不能被public,private,protected修斯。使用局部内部类可以将自身对外部完全的隐藏起来。除了它所在的方法,不能通过任何办法知道它的存在。局部内部类不仅能访问外部类结构,还能访问自身所在方法的局部变量。
class Outer{
String name="Outer";
public Comparable getComparable(String name){
class MyComparable implements Comparable{
@Override
public int compareTo(Object o) {
System.out.println("外部类name:"+Outer.this.name+",内部类name:"+name);
return 0;
}
}
return new MyComparable();
}
public Comparable getComparable2(final String name){
return new Comparable() {
@Override
public int compareTo(Object o) {
System.out.println("外部类name:"+Outer.this.name+",内部类name:"+name);
info();
return 0;
}
};
}
public void info(){
System.out.println("info");
}
}
public class Demo{
public static void main(String[] args) {
Outer outer=new Outer();
Comparable comparable = outer.getComparable("Inner");
comparable.compareTo(1);
System.out.println("==================================");
Comparable hh = outer.getComparable2("inner");
hh.compareTo(1);
}
}
输出:
外部类name:Outer,内部类name:Inner
==================================
外部类name:Outer,内部类name:inner
info