一、什么是内部类
1.1 内部类概述
内部类,顾名思义,在类内部的类,内部类就是将一个类的定义放在另一个类的定义内部,这里的"另一个类"就是外部类。内部类又称为嵌套类,外部类又叫做为封闭类。
1.2 内部类有哪些
从广义上来说内部类可以被分为四种,分别是:
- 成员内部类
- 静态内部类
- 局部内部类
- 匿名内部类
具体的概念特点和用法我们下面分类总结。
二、成员内部类
2.1 概述
成员内部类,是最普通的内部类,它就是单纯的在类里面,和属性及方法是并列的,这样看来,这个内部类更像是对应外部类的成员,需要注意的是,成员内部类是不能用static修饰的,否则的话就变成了静态内部类。
2.2 语法形式
语法如下:
java
public class Outer{//外部类
...
class Inner{//内部类
...
}
}
2.3 成员内部类的创建
根据我们学过的类的知识可以知道,一个类没有创建对象时,他的非静态成员是不能直接调用的,同样的,成员内部类也一样。
成员内部类必须依附于外部类而存在,我们可以把它看作是外部类的成员,想要创建它的对象,就必须先创建外部类的对象,创建成员内部类的方法一般如下:
java
外部类.内部类 对象名 = 外部类对象.new 内部类();
//或者
外部类.内部类 对象名 = new 外部类().new 内部类();
2.4 特点
1)成员内部类可以无条件访问外部类的所有成员属性和成员方法(包括private成员和静态成员)。
2)成员隐藏:当内部类和外部类拥有同名的成员变量或者方法时,会发生隐藏现象,即默认情况下在内部类中访问的是内部类自己的成员变量、方法。
如果想访问外部类的成员变量或方法,需要通过外部类.this访问,如下:
java
外部类.this.成员变量
外部类.this.成员方法
3)在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问内部类成员,例如:
java
public class Outer{//外部类
...
class Inner{//内部类
...
}
Inner inner = new Inner();
inner.属性名;
inner.方法名;
}
三、静态内部类
3.1 概述
静态内部类和成员内部类在写法上的区别在于,静态内部类前面是被static修饰的。
同样,因为他是静态的,所以静态成员的特点他同样具有。
3.2 语法形式
java
public class Outer{//外部类
...
static class Inner{//内部类
...
}
}
3.3 成员内部类的创建
静态内部类不需要依赖于外部类的对象
java
外部类.内部类 对象名 = new 外部类.内部类()
3.4 特点
1)访问静态内部类的静态成员,不需借助于内部类对象,可直接通过内部类类名访问。
2)静态内部类不能使用外部类的非static成员变量或者方法,因为静态内部类是静态的,是归属于当前类的,是所有对象公用的,
所以在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员是依附于具体的对象的。
四、局部内部类
4.1 概述
局部内部类又叫方法内部类或本地(Local)内部类,是定义在方法内部的一个类,类似于方法的局部变量。且作用域是仅在定义它的块中。
局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及
static修饰符的。
需要注意的是:如果局部内部类是定义在外部类的静态方法中的,则它无法访问外部类的非静态成员。
4.2 语法形式
语法如下:
java
public class Outer{
public void method(){
class Inner{//局部内部类
...
}
}
}
4.3 局部内部类的创建
局部内部类是在外部类的方法里创建的,所以直接可以在方法中创建对象,作用域仅限于创建之后的块内:
java
public void m1(){
//局部内部类
class Inner{
int b;
public void m2(){
System.out.println("c = " + c);//1
System.out.println("a = " + a);//10
//a = 100;
System.out.println("Inner.m2");
}
}
//创建局部内部类对象
Inner inner = new Inner();
System.out.println("inner.b = " + inner.b);//0
inner.m2();
}
4.4 特点
它和成员内部类的区别在于局部内部类的访问仅限于方法内或者代码块内,其他特性与成员内部类一致。
1)局部内部类类似于局部变量,定义在方法中。
2)局部内部类可以直接访问外部类的私有成员从而不破坏封装
3)局部内部类对象的创建只能在定义它的方法中(局部内部类存在作用范围的概念)。
4)局部内部类可以访问外部类的局部变量,但是必须加上final
注意:jdk8.0以后,在内部类中访问外部类的局部变量默认添加final
五、匿名内部类
5.1 概述
匿名内部类就是没有类名的局部内部类,是一种特殊的局部内部类,局部内部类的一切特征,匿名内部类都具备。
5.2 语法形式
因为是匿名的,所以没有对应的类名,那么如何创建他的对象呢?
因为匿名内部类没有类名,所以它不能像正常类一样创建对象,它只能在定义类的同时创建对象。
下面我展示一种使用方式,这种内部类对象的定义可以如下定义,:
在父子类的继承关系中:
java
父类名 对象名 = new 父类名(){
//重写父类的某些方法 或 实现父类中的抽象方法
}
在与接口之间的实现关系中:
java
接口名 对象名 = new 接口名(){
//实现接口中的抽象方法
}
通过这两种格式,我们可以看出,因为这个内部类没有类名,所以可以看作是一次性的创建使用,且它的创建必须要求继承一个父类或实现一个接口。
所以我们可以使用父类,或者是接口来接收这个对象的创建,其实你也应该看出来了,这其实是一种多态的使用。
5.3 特点
1)匿名内部类是平时我们编写代码时用得最多的,可以说是频繁使用,大量使用,使用匿名内部类最大的优势就是方便。
2)无论是匿名类还是正常子类,都需要实现父类中抽象的方法。
匿名类和正常类的区别就是没有类名,因此它不能随时随地创建对象,只能在创建类的时候创建对
象。类名用父类的类名,构造方法用父类的构造方法。
接口也是一样的。
3)只能创建该匿名内部类的一个对象,优点:减少冗余代码,不打断程序员的思路,缺点:可读性不好。
匿名内部类非常重要,开发中频繁使用,务必要会!!!