目录
内部类:
1.把一个类放在另一个类的内部定义,称为内部类(innerclasses)。
2.内部类可以使用public、default、protected 、private以及static修饰。而外部顶级类(我们以前接触的类)只能使用public和default修饰。
内部类的作用:
1. 内部类提供了更好的封装。只能让外部类直接访问,不允许同一个包中的其他类直接访问。
2. 接口只是解决了多重继承的部分问题,而内部类使得多重继承的解决方案变得更加完整。
一、非静态内部类
非静态内部类可以直接访问外部类的成员,但是外部类不能直接访问非静态内部类成员。
非静态内部类不能有静态方法、静态属性和静态初始化块。
外部类的静态方法、静态代码块不能访问非静态内部类。
1.创建非静态内部类
class Wai{
class Nei{
//内部类成员
}
//外部类成员
}
2.在外部类中访问内部类
先创建内部类对象,在通过内部类对象访问内部类成员
范例:
public class InnerClass {
public static void main(String[] args) {
Wai w = new Wai();
w.myVoid();
}
}
class Wai{
class Nei{ //创建非静态内部类
int i = 5; //内部类成员
}
public void myVoid() { //外部类成员
Nei n = new Nei(); //创建一个内部类对象
int j = n.i; //访问内部类成员
System.out.println("内部类变量的值为:"+j);
}
}
3.在外部类外访问内部类
基本语法:Wai.Nei wn = new Wai().new Nei();
也可以分成两条:Wai w = new Wai(); Wai.Nei wn = w.new Nei();
public class InnerClass {
public static void main(String[] args) {
Wai.Nei wn = new Wai().new Nei();
System.out.println(wn.s);
}
}
class Wai{
class Nei{ //创建非静态内部类
int i = 5; //内部类成员
String s = "Hello";
}
}
注意:如果 内部类 [成员] 被private修饰,则外部类外访问内部类时不能访问
4.在内部类中访问外部类
内部类可以访问外部类所有成员,不需要添加内容,就像成员方法间调用一样
public class InnerClass {
public static void main(String[] args) {
Wai.Nei wn = new Wai().new Nei();
wn.myVoid();
}
}
class Wai{
int i = 8;
class Nei{
public void myVoid() {
System.out.println("外部类成员变量值为:"+i);
}
}
}
5.补充
public class InnerClass {
public static void main(String[] args) {
Wai.Nei wn = new Wai().new Nei();
wn.myVoid();
}
}
class Wai{
int i = 8;
class Nei{
int i = 9;
Wai ww = new Wai();
public void myVoid() {
System.out.println(i); //结果为9:内外部都有i,则为内部中i的值,否则为外部
System.out.println(ww.i); //8:对象调用外部类成员i的值
System.out.println(this.i); //9:this.i指当前类中i的值
System.out.println(Wai.this.i); //8:类名.this 指外部类
}
}
}
二、局部内部类
局部内部类的作用范围和局部变量是相同的,只在局部起作用
1.局部内部类的创建
public class InnerClass {
public static void main(String[] args) {
Wai w = new Wai();
w.myVoid();
}
}
class Wai{
public void myVoid() {
class Nei{ //定义局部内部类
int i = 5; //局部内部类中的成员变量
}
Nei n = new Nei();
System.out.println(n.i);
}
}
2.在局部内部类中访问外部类成员变量
直接调用即可
3.在局部内部类中访问外部类的局部变量
外部类中的局部变量必须要加final,否则会报错
原因:非final局部变量的生命周期比局部内部类短
public class InnerClass {
public static void main(String[] args) {
Wai w = new Wai();
w.myVoid();
}
}
class Wai{
public void myVoid() {
final int i = 9; //必须加final,否则会报错
class Nei{
public void myNeiVoid() {
//访问外部类的成员变量
System.out.println("外部类的局部变量为:"+i);
}
}
Nei n = new Nei();
n.myNeiVoid();
}
}
4.静态方法中的局部内部类
局部内部类可以访问外部类的所有成员,包括私有成员。但在静态方法中定义的局部内部类,只能访问外部的静态成员
示例:(会报错)
public class InnerClass {
public static void main(String[] args) {
Wai w = new Wai();
w.myVoid();
}
}
class Wai{
int i = 9; //需要声明为static类型
public static void myVoid() {
class Nei{
public void myNeiVoid() {
//访问外部类的成员变量
System.out.println("外部类的局部变量为:"+i);
}
}
Nei n = new Nei();
n.myNeiVoid();
}
}
三、静态内部类
1.创建静态内部类
class Wai{
static class Nei{ //内部类成员 }
//外部类成员
}
2.实例化 及 成员调用
1. 当一个静态内部类对象存在,并不一定存在对应的外部类对象。 因此,静态内部类的实例方法不能直接访问外部类的实例方法。
2. 静态内部类看做外部类的一个静态成员。 因此,外部类的方法中可以通过:“静态内部类.名字”的方式访问静态内部类的静态成员,通过 new 静态内部类()访问静态内部类的实例。
class Outer{
//相当于外部类的一个静态成员
static class Inner{
}
}
public class InnerClass {
public static void main(String[] args) {
//通过 new 外部类名.内部类名() 来创建内部类对象
Outer.Inner inner = new Outer.Inner();
}
}
四、匿名内部类
1.创建匿名内部类
匿名内部类的声明必须是基于继承或者是基于接口的,创建格式如下:
new NeiFather(){
//匿名内部类
};
NeiFather 是匿名内部类继承的父类的类名,使用 new 同时创建了匿名内部类的对象。
public class NeiClass {
public static void main(String[] args) {
//创建匿名内部类
Nei n = new Nei() {
//实现接口中的方法
public void myVoid() {
System.out.println("匿名内部类的方法");
}
};
n.myVoid(); //调用匿名内部类中的方法
}
}
//创建匿名内部类将实现的接口
interface Nei{
//接口中的方法
public void myVoid();
}
2.匿名内部类的初始化
匿名内部类没有名称,所以没有构造器,这时初始化工作便成了问题
方法:创建一个非静态语句块,将所有初始化的成员变量放在该语句块中,这样在匿名内部类中就可以调用这些成员变量了。
public class NeiClass {
public static void main(String[] args) {
//创建匿名内部类
NeiFather n = new NeiFather() {
//非静态语句块
{
i = 9;
}
//重写父类中的方法
public void myVoid() {
System.out.println("匿名内部类中成员变量值为:"+i);
}
};
n.myVoid();
}
}
//创建匿名内部类将继承的父类
class NeiFather{
int i;
//父类中的方法
public void myVoid() {
System.out.println("这是内部类父类中的方法");
}
}