一、内部类概述
1、什么是内部类
定义在一个类的内部的类,就是所谓的内部类
比如类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类
public class Outer{ //外部类
class Inner{ //内部类
}
}
编译后
Outer$Inner .class
Outer.class
2、内部类的特点
➢编译之后可生成独立的字节码文件。
➢内部类可直接访问外部类的私有成员,而不破坏封装
。
➢可为外部类提供必要的内部功能组件。
3、内部类的分类
➢定义在类的内部:
成员内部类、静态内部类
➢定义在类的方法内部:
局部内部类、匿名内部类
内部类分类演示
1、成员内部类
- 1、定义在类的内部,并且和成员属性、成员方法同一级;
- 2、成员内部类可以正常访问外部类的资源,不管是否是静态;
- 3、成员内部类中可以和外部类中所定义的变量重复,但是注意
- 如果在内部类中使用该重名的资源的话,是就近原则;
- 4、成员内部类里面不可以定义静态资源;
- 5、外部类想访问成员内部类的资源的话,需要先通过外部类的对象
- 来.new 内部类才能获取到内部类对象!
1.在类的内部定义,与实例变量、实例方法同级别的类;
2.内部类中的变量可以和外部类重名;
3.内部类中不能定义static修饰的成员资源,但是可以定义常量;
public class MemberInnerClass {
//成员属性
int a = 100;
//定义一个静态资源
static int b = 200;
//成员方法
public void test() {
System.out.println("这是外部类的成员方法");
}
//静态方法
public static void test1() {
System.out.println("这是外部类所定义的静态方法");
}
//定义一个成员内部类
class Inner{
//尝试访问外部类的资源
// int x = a;//能够正常访问外部类的资源
//尝试定义一个和外部类的属性名重名的变量,就近原则
String a = "abc";
//尝试在内部类里面定义静态资源
// static int x = 10;//不允许定义
// public static void test4() {
//
// }
//允许你定义常量
static final int MAX_VALUE=1000;
//尝试定义一个方法
public void test2() {
//可以在内部类中访问外部类的方法,不区分静态不静态
test();
test1();
System.out.println("我是内部类的方法");
}
}
public void test7() {
Inner inner = new Inner();
}
}
class Test{
//尝试在外部类中访问内部类的资源
public static void main(String[] args) {
MemberInnerClass outer = new MemberInnerClass();
MemberInnerClass.Inner inner = outer.new Inner();
//访问里面的资源
System.out.println(inner.a);
inner.test2();
System.out.println(MemberInnerClass.Inner.MAX_VALUE);
}
}
2、静态内部类
- 静态内部类
- 1、静态内部类在使用和访问上和成员内部类的唯一区别就是
- 它具备了静态的特点;
- 2、在其他类中想访问外部类中的静态类里面的非静态资源,就是需要
- 来构建一个静态类的对象,但是因为它具备了静态的特点,所以我们只
- 需要通过外部类.静态内部类就可以来构建对象;
public class StaticInnerClass {
//定义一些外部类资源
int a = 100;
static int b = 200;
public void test1() {
System.out.println("我是外部类的成员方法");
}
public static void test2() {
System.out.println("我是外部类的静态方法");
}
//定义一个静态内部类
static class Inner{
//尝试访问外部类资源
// int x1 = a;//无法访问非静态资源
int x2 = b;
//是否允许和外部类资源同名
static int a = 1000;//允许同名
//定义一个普通方法
public void test3() {
//访问外部类的方法
// test1();//不能访问非静态资源方法
test2();
System.out.println("这是内部类的普通方法");
}
public static void test4() {
System.out.println("这是内部类的静态方法");
}
}
public void test5() {
System.out.println(Inner.a);
Inner.test4();
Inner inner = new Inner();
System.out.println(inner.x2);
inner.test3();
}
}
class Test2{
public static void main(String[] args) {
//在其他类中访问另外一个类的静态内部类中的静态资源
System.out.println(StaticInnerClass.Inner.a);
StaticInnerClass.Inner.test4();
//在其他类中访问另外一个类的静态内部类中的非静态资源
StaticInnerClass.Inner outer = new StaticInnerClass.Inner();
System.out.println(outer.a);
outer.test3();
}
}
3、局部内部类
- 局部内部类的使用
- 1、所谓的局部内部类就是定义在方法里面的类,这个类像局部变量一样
- 所以,就叫局部内部类
- 2、局部内部类定义出来就是在当前方法有效,除了该方法,都不能正常访问;
public class LocalInnerClass {
public static void main(String[] args) {
//jdk1.8之前想在局部内部类中访问外部类资源,外部类资源必须要加final修饰
// final int a = 100;
int a = 100;
class Inner{
//访问外部类资源
int x = a;
int b = 200;
public void test1() {
System.out.println(123);
}
}
//构建一个局部内部类的对象
Inner inner = new Inner();
inner.test1();
System.out.println(inner.b);
}
//局部内部类出了定义的方法,哪怕还在外部类的内部都无法进行访问
}
class Test3{
//局部内部类是无法在类的外边进行访问的
}
4、匿名内部类 重点
匿名内部类
1、匿名内部类是一个特殊的局部内部类,即,它是一个没有类名的局部内部类;
2、跟局部内部类一样,它都是定义在方法内部的类,既然是定义在方法的内部,
那么它的作用就肯定不是为了封装,而是为了实现某个特定的行为动作
,
那么如果说是个新类的行为动作的话,我们没有必要定义在内部,而是直接单独去定义这个类就行了,因为这个类以后还会用得上,只有一种情况,就是这个类我们只需要使用一次就不再用了,即作为一个子类重写父类的某个方法,该方法重写之后,立马使用,且只使用一次,下次想再次使用,那么业务逻辑会跟这次的不一样,需要重写继承
;
3、先定义出几个父类:普通的类、接口、抽象类
1、父类 对象 = new 父类(){ 重写父类中的方法 };
使用匿名内部类,直接重写父类的方法,省去创建子类继承父类的过程和创建子类对象的过程。
class F1{
public void test1() {
System.out.println("这是父类F1的test1方法");
}
}
public class NoNameInnerClass {
public static void main(String[] args) {
//构建了一个局部内部类,继承F1这个父类,并且重写它的test1方法
F1 f1 = new F1() {
public void test1() {
System.out.println("这是局部内部类,F1的子类");
};
};
}
2、接口 对象=new 接口(){ 重写接口中的方法 };
使用匿名内部类,直接重写接口中的方法,省去创建实现类实现接口的过程和创建实现类对象的过程。
interface F3{
public void test3();
}
public class NoNameInnerClass {
public static void main(String[] args) {
//再次使用匿名内部类来重写F3接口中的抽象方法
new F3() {
public void test3() {
System.out.println("这是匿名内部类,F3的子类");
}
}.test3();
}
}
3、抽象类 对象=new 抽象类(){ 重写抽象类中的方法 };
使用匿名内部类,直接重写抽象类中的方法,省去创建实现类实现抽象类的过程和创建实现类对象的过程。
abstract class F2{
public abstract void test2();
}
public class NoNameInnerClass {
public static void main(String[] args) {
//使用匿名内部类来重写F2类的方法
new F2() {
public void test2() {
System.out.println("这是匿名内部类,F2的子类");
}
}.test2();
}
}