1、内部类:属于类的成员之一,类的内部又定义类,外层的class称为外部类,内部的class称为内部类。
设计了某个类,根据需求发现其内部又需要定义一个独立的内部结构,此时就考虑将其定义为内部类,内部类依赖于外部类,不可能独立存在。
举例:
?? ?母亲 和其 腹中的胎儿
备注:外部类的权限修饰只能用public或者缺省,而内部类可以用所有的四种权限。
2、内部类的分类:
定义位置:
1)、成员内部类:?定义在类的成员位置;
2)、局部内部类: 定义在类的局部位置;?
成员内部类细分:
1)、非静态成员内部类:非静态内部类;
2)、静态成员内部类: ?静态内部类;
局部内部类细分:
1)、局部内部类:?? ?定义在局部位置的有名类;??
2)、匿名内部类:?? ?定义在局部位置的匿名类;
1、匿名内部类:内部类中,匿名内部类使用率最高,所以这里先进行说明,其它的内部类直接后面放代码里进行说明。
引入场景:
?? ?类/接口内部定义了某方法,我需要使用该方法,但是发现方法体的逻辑不适合,
?? ?根据之前学习过的技术,我们就定义一个类,让该类去继承父类/实现接口,
?? ?重写其内部的方法,在外界实例化对象,对象调用方法完成需求。
?? ?【问题】:辛辛苦苦设计完一个类,但是在外界只需要使用很少的次数(比如:一次)
?? ? ? ? ? ? ?那么有点浪费了!!!
?? ?【解决】:可以使用匿名内部类解决上述的问题
格式:
两种情况:
情况一:和父类有关
模板:
?? ?new 父类名(){
?? ??? ?//设计匿名子类的成员
?? ?};
情况二:和接口有关
模板:
?? ?new 接口名(){
?? ??? ?//设计匿名实现类的成员
?? ?};
解析格式:
?? ?
内部包含两个环节:
环节一:设计匿名子类/实现类
环节二:创建匿名子类/实现类的对象
备注:匿名内部类不能赋值给对象引用,要调用时只能匿名类自己直接在后面.操作进行调用方法,例如下面这样三个例子:
//匿名内部类
new Father(){
//重写method方法
@Override
public void method() {
System.out.println("重写method");;
}
}.method();
//匿名内部类
new Object(){
public void myMethod() {
System.out.println("匿名内部类自己的方法");
}
}.myMethod();
//匿名内部类
new Inter(){
//重写实现接口的interMethod方法
@Override
public void interMethod() {
System.out.println("实现接口interMethod");
}
}.interMethod();
3、成员内部类的几种情况:
1)、非静态内部类:
//外部类
public class Outer {
//属性
int a = 10;
static int b = 20;
private int c = 30;
//方法
public void outM1() {
System.out.println("out...m1");
}
public static void outM2() {
System.out.println("out...m2");
}
public void outM5() {
/*
非静态方法内部访问非静态内部类的成员
步骤如下:
1).创建非静态内部类对象
2).非静态内部类对象访问其内部成员
*/
Inner in = this.new Inner();
System.out.println(in.i);
in.inM3();
}
public static void outM6() {
/*
静态方法内部访问非静态内部类的成员
步骤如下:
1).创建外部类对象
2).通过外部类对象去创建非静态内部类对象
3).非静态内部类对象访问其内部成员
*/
Outer o = new Outer();
Inner in = o.new Inner();
System.out.println(in.i);
in.inM3();
}
//设计非静态内部类
class Inner{
int i = 100;
//非静态内部类中不能定义静态属性
// static int j = 200;
//非静态内部类中可以定义常量
static final double PI = 3.14;
public void inM3() {
System.out.println("in...m3");
}
//非静态内部类中不能定义静态方法
// public static void inM4() {
// //...
// }
{}
//非静态内部中不能定义静态代码块
// static{}
public void test() {
//访问外部类的属性
System.out.println(a);
System.out.println(Outer.this.a);
System.out.println(b);
System.out.println(Outer.b);
System.out.println(c);
//访问外部类的方法
Outer.this.outM1();
Outer.outM2();
}
}
}
public class Test {
public static void main(String[] args) {
/*
在外界(比如:测试类),访问非静态内部类的成员
步骤如下:
1).创建外部类对象
2).通过外部类对象去创建非静态内部类对象
3).非静态内部类对象访问成员
*/
Outer o = new Outer();
Outer.Inner in = o.new Inner();
System.out.println(in.i);
in.inM3();
}
}
2)、静态内部类:
public class Outer {
//属性
int a = 10;
static int b = 20;
private int c = 30;
//方法
public void outM1() {
System.out.println("out...m1");
}
public static void outM2() {
System.out.println("out...m2");
}
public void outM5() {
/*
外部类非静态方法内部可以直接访问静态内部类的静态成员(属性、方法)
通过类名.静态成员
*/
System.out.println(Inner.j);
Inner.inM4();
/*
外部类非静态方法内部不可以直接访问静态内部类的非静态成员(属性、方法)
但是可以间接访问,步骤如下:
1).创建静态内部类对象
2).通过静态内部类对象访问其非静态成员
*/
Inner in = new Inner();
System.out.println(in.i);
in.inM3();
}
public static void outM6() {
/*
外部类静态方法内部可以直接访问静态内部类的静态成员(属性、方法)
通过类名.静态成员
*/
System.out.println(Inner.j);
Inner.inM4();
/*
外部类静态方法内部不可以直接访问静态内部类的非静态成员(属性、方法)
但是可以间接访问,步骤如下:
1).创建静态内部类对象
2).通过静态内部类对象访问其非静态成员
*/
Inner in = new Inner();
System.out.println(in.i);
in.inM3();
}
//设计静态内部类
static class Inner{
int i = 100;
static int j = 200;
public void inM3() {
System.out.println("in...m3");
}
public static void inM4() {
System.out.println("in...m4");
}
public void test() {
/*
静态内部类非静态方法内部可以直接访问外部类的静态成员:
直接通过类名.静态成员即可
*/
// System.out.println(a);
System.out.println(Outer.b);
Outer.outM2();
/*
静态内部类非静态方法内部不可以直接访问外部类的非静态成员:
必须先创建外部类对象,在通过对象名.非静态成员
*/
Outer o = new Outer();
System.out.println(o.a);
System.out.println(o.c);
o.outM1();
}
public static void test2() {
/*
静态内部类静态方法内部可以直接访问外部类的静态成员:
直接通过类名.静态成员即可
*/
// System.out.println(a);
System.out.println(Outer.b);
Outer.outM2();
/*
静态内部类静态方法内部不可以直接访问外部类的非静态成员:
必须先创建外部类对象,在通过对象名.非静态成员
*/
Outer o = new Outer();
System.out.println(o.a);
System.out.println(o.c);
o.outM1();
}
}
}
public class Test {
public static void main(String[] args) {
//访问静态内部类的静态成员(属性、方法) ==> 类名直接访问
System.out.println(Outer.Inner.j);
Outer.Inner.inM4();
/*
访问静态内部类的非静态成员(属性、方法)
先创建静态内部类对象,在通过对象访问非静态成员
*/
Outer.Inner in = new Outer.Inner();
System.out.println(in.i);
in.inM3();
}
}
4、关于内部类的一个小案例:
class Wai{
int a = 10;
class Nei{
int a = 100;
public void test() {
int a = 1000;
System.out.println("局部变量a=" + a); //就近原则 a=1000
System.out.println("非静态内部类成员变量a=" + this.a); //a=100
System.out.println("外部类成员变量a=" + Wai.this.a); //a=10
}
}
}
public class Exer {
public static void main(String[] args) {
Wai w = new Wai();
Wai.Nei n = w.new Nei();
n.test();
}
}
本电子书目录:《Java基础的重点知识点全集》