内部类
4种内部类
1. 局部内部类
1. 匿名内部类
1. 成员内部类
1. 静态内部类 (成员内部类,静态内部类是放在外部类的成员位置上,本质是一个成员)
静态方法只能访问静态成员,非静态方法可以访问静态和非静态成员
静态方法和类一起加载,非静态方法只有在创建对象时才会加载。所以才有了静态方法不能直接调用非静态(因为静态方法加载时类还没有初始化也就还没有非静态方法),非静态方法可以直接调用静态方法(因为非静态方法加载时静态方法早就加载了)
一.局部内部类
局部内部类
public class JuBuOut {
private int a = 1001;
public static void main(String[] args) {
JuBuOut outBody = new JuBuOut();//创建外部类的对象,用对象调用外部类方法
outBody.out01();//方法执行,创建内部类,之后创建内部类对象,对局部方法进行调用
}
void out() {
System.out.println("局部内部类可以直接调用外部方法,比如调用我");
}
void out01() {
System.out.println("我是外部方法,我要在此创建一个局部内部类,");
final class in01 { //1.局部内部类(本质还是一个类) 2.不可以加访问修饰符public等,但可以加final(final 不能被继承)
//3.局部内部类的作用域只在定义我的方法中或者代码块中
private int a = 100;
void in001() {
System.out.println("我就是局内内部类中的方法,我要开始访问我的局部变量和外部变量");
System.out.println(a);//局部内部类自己的局部变量
System.out.println(JuBuOut.this.a);//4.用类名加.this+变量名就可以访问到外部成员变量
//JuBuOut.this的本质就是外部类的对象,谁调用了out01,JuBuOut.this就是哪个对象
out(); //5.局部内部类可以直接调用外部方法
}
}
in01 inBody = new in01();//6.外部类在方法中直接创建内部类(in01)对象,然后调用in001方法
inBody.in001();
}
}

二.匿名内部类
匿名内部类的基本语法
new 类或接口(参数列表){ 类体 }; //不要忘记有分号( ; )
匿名内部类的两种使用方式
点击查看代码
public class NeiBuLeiTest {
public static void main(String[] args) {
NeiBuLeiTest a = new NeiBuLeiTest();
a.method();
}
public void method() {
//第一种匿名内部类创建方法
Person p1 = new Person() {
@Override
void speak() {
System.out.println("匿名内部类重写了speak(方法)");
}
};
p1.speak();//第一种调用方法
//第二种匿名内部类创建方法
new Person() {
@Override
void city(String name) {
super.city(name);
}
}.city("China");//第一种调用方法
}
}
class Person {
void speak() {
System.out.println("喜欢说话");
}
void city(String name) {
System.out.println("匿名内部类调用方法传来的参数:" + name);
}
}

public class NiMingClass { //外部其他类
public static void main(String[] args) {
WaiBu waibu1 = new WaiBu();
waibu1.method();
}
}
class WaiBu { //外部类
private int n = 10;//属性
//它的本质是类(内部类),该类没有名字,同时还是一个对象;
//匿名内部类是定义在外部类的局部位置(比如方法中) 并且没有类名
public void method() { //方法
//1.基于接口的匿名内部类 (传统方法是写一个类,实现该接口,并创建对象)
//2.若实现该接口的类只使用一次,后面不再使用,可以使用匿名内部类来简化开发
JieKou eg = new JieKou() { //3.eg的编译类型是JieKou
@Override
public void cry() {
System.out.println("匿名内部类好令人难过啊");
}
};
System.out.println("eg的运行类型" + eg.getClass());//4.eg的运行类型(匿名内部类)是WaiBu$1
eg.cry();//5.jdk底层在创建匿名内部类 WaiBu$1,立马创建了一个WaiBu$1的实例,并且把地址返回给 eg
//6.匿名内部类使用一次,就不能再使用(不能再创建 new WaiBu$1(); ),但是 eg可以反复调用cry();方法
//基于类的匿名内部类
Father father = new Father("老张") {//这里的("老张")参数列表会传给Father类的构造器
@Override
public void test() {
System.out.println("我在这重写了test()方法");
}
};
System.out.println("father的运行类型" + father.getClass());
father.test();
}
}
interface JieKou { //接口
public void cry();
}
class Father {
public Father(String name) { //构造器
System.out.println("传过来的name:" + name);
}
public void test() { //方法
}
}

三.成员内部类
public class ChengYuan {
public static void main(String[] args) {
Out01 out01 = new Out01();
out01.run01();
//外部其他类,使用成员内部类的两种方式
//第一种方式
//out01.new In01();相当于new In01()是out01对象的一个成员(一种语法)
Out01.In01 in02 = out01.new In01();
in02.test();
//第二种方式 在外部类中,编写一个方法,可以返回In03的对象实例
Out01.In01 in03 = out01.getIn03Instance();
in03.test();
}
}
class Out01 { //外部类
private int a = 53;
String name = "啊哈";
void test02() {
System.out.println(" 成员内部类可以直接调用test02()方法 ");
}
public class In01 {//1.成员内部类(定义在外部类的成员位置上),可以访问外部类的所有成员,包括私有的
//(作用域和外部类其他成员一样,为整个类体)
//2.可以添加任意访问修饰符public.private.默认.protected,因为它的地位就是一个成员
void test() {
System.out.println(" 访问外部类的成员变量 " + a + "和" + name);
test02();//成员内部类可以直接调用test02()方法
System.out.println("++++++++++++++++");
}
}
public In01 getIn03Instance() { //第二种 外部其他类,使用成员内部类创建方式的方法
return new In01(); //方法返回一个In03的实例
}
void run01() { //创建一个成员内部类对象
In01 in01 = new In01();
in01.test();//调用成员内部类的方法
}
}

四.静态内部类
public class StaticInClass { //外部其他类
public static void main(String[] args) {
Outout out1 = new Outout();
System.out.println("第一次");
out1.eatTest();
//外部其他类 访问 静态内部类
//方式一 静态内部类可以通过类名直接访问(前提是满足访问权限,不可以是private)
Outout.InIn in1 = new Outout.InIn();
System.out.println("第二次");
in1.eat();//调用静态内部类的方法
//方式二,编写一个方法,可以返回in02的对象实例
Outout.InIn in02 = out1.getin02();
System.out.println("第三次");
in02.eat();
//由外部类直接调用静态方法,返回in03的对象实例
Outout.InIn in03 = Outout.getin03();
System.out.println("第四次");
in03.eat();
}
}
class Outout { //外部类
private static String aa = "外部类";
static void kfc() {
System.out.println("静态内部类调用了我, 快v我50");
}
public static class InIn {//1.静态内部类 (作用域和外部类其他成员一样,为整个类体)
//2.可以添加任意访问修饰符public.private.默认.protected,因为它的地位就是一个成员
private static String aa = "静态内部类";
public void eat() { //可以访问外部类的所有静态成员,包括私有的,但不能直接访问非静态成员
System.out.println("访问外部类的成员变量aa:" + Outout.aa + " 静态内部类的aa:" + aa);
//如果外部类和静态内部类的成员重名时,默认遵循就近原则,
// 如果想访问外部类的重名成员时,则可以使用(外部类类名.成员变量名)
kfc();
}
}
public InIn getin02() {
return new InIn();//返回一个InIn类的实例in02
}
public static InIn getin03() { //也可以用静态方法,然后有外部类直接调用此方法
return new InIn();
}
void eatTest() {
InIn inin1 = new InIn();
inin1.eat();
}
}


浙公网安备 33010602011771号