文章目录
今日提要:内部类
1.内部类
定义:Java在一个类中定义一个类,这个类被称为内部类,定义这个内部类所在的类叫做外部类;
2.成员内部类
定义:
- 在一个类中定义的变量叫做成员变量,定义的方法叫做成员方法,定义的类叫做成员内部类;
- 成员内部类可以访问外部类的所有成员变量和成员方法,而外部类也可以访问成员内部类的变量和方法;
- 对象的创建:外部类名.内部类名 变量名 = new 外部类名().new 内部类名();;
- 上代码:
java
public class ExternalClass {//外部类
//外部类成员属性
int x = 10;
String a = "这是个外部类的成员变量";
//外部类成员方法
public void testExternalOne() {
System.out.println("这是个外部类的成员方法 testExternalOne");
}
public void testExternalTwo() {
InsideClass ins = new InsideClass();
System.out.println("外部类调用内部类的成员变量: " + "内部类变量 xx = " + ins.xx + " , " + "内部类变量 aa = " + ins.aa);
System.out.print("外部类调用内部类的成员方法: ");
ins.testInsideOne();
}
//成员内部类
class InsideClass{//成员内部类
//内部类成员属性
int xx = 20;
String aa = "这是个内部类的成员变量";
//内部类成员方法
public void testInsideOne() {
System.out.println("这是个内部类的成员方法 testInsideOne");
}
public void testInsideTwo() {
System.out.println("内部类调用外部类的成员变量: " + "外部类变量 x = " + x + " , " + "外部类变量 a = " + a);
System.out.print("内部类调用外部类的成员方法: ");
testExternalOne();
}
}
public static void main(String[] args) {
ExternalClass test0 = new ExternalClass();
test0.testExternalOne();
test0.testExternalTwo();
System.out.println();
ExternalClass.InsideClass test1 = new ExternalClass().new InsideClass();
test1.testInsideOne();
test1.testInsideTwo();
}
}
运行结果:
java
这是个外部类的成员方法 testExternalOne
外部类调用内部类的成员变量: 内部类变量 xx = 20 , 内部类变量 aa = 这是个内部类的成员变量
外部类调用内部类的成员方法: 这是个内部类的成员方法 testInsideOne
这是个内部类的成员方法 testInsideOne
内部类调用外部类的成员变量: 外部类变量 x = 10 , 外部类变量 a = 这是个外部类的成员变量
内部类调用外部类的成员方法: 这是个外部类的成员方法 testExternalOne
- 外部类访问内部类的成员的时候,需要先创建对象,内部类访问外部类成员的时候,可以直接访问;
- 还有需要重点注意的是,如果内外部类相互调用,极易产生递归调用,代码陷入死循环,别问我是怎么知道的
- 另外
ExternalClass.InsideClass test1 = new ExternalClass().new InsideClass();
等价于ExternalClass test0 = new ExternalClass(); ExternalClass.InsideClass test1 = test0.new InsideClass();
3.局部内部类
定义:
- 局部内部类(方法内部类),它定义在方法内;
- 局部内部类可以访问外部类的所有成员变量和成员方法;
- 局部内部类的成员变量和成员方法,只能在定义这个局部内部类的方法中访问;
- 上代码:
java
public class ExternalClass {//外部类
//外部类成员变量
int x = 10;
String a = "你好!我是个外部类的成员变量";
//外部类成员方法
public void testExternalOne() {
System.out.println("你好!我是外部类成员方法:testExternalOne();");
// InsideClass i = new InsideClass();//局部内部类在外部类的其它成员方法中不可见
}
public void testExternalTwo() {
//外部类成员方法中的变量
int y = 20;
String b = "你好!我是外部类成员方法中的变量";
//定义局部内部类
class InsideClass{
//局部内部类成员变量
int xx = 30;
String aa = "你好!我是局部内部类的成员变量";
//局部内部类成员方法
void testInsideOne() {
System.out.println("你好!我是局部内部类的成员方法testInsideOne(),我将访问外部类的成员变量:" + "外部类成员变量x = " + x + " , " + "外部类成员变量a = " + a);
System.out.print("你好!我是局部内部类的成员方法testInsideOne(),我将访问外部类的成员方法:");
testExternalOne();
System.out.print("你好!我是局部内部类的成员方法testInsideOne(),我将访问定义我的外部类的成员方法的成员变量:");
System.out.println("定义局部内部类的外部类成员方法的成员变量y = " + y + " , " + "定义局部内部类的外部类成员方法的成员变量b = " + b);
System.out.print("你好!我是局部内部类的成员方法testInsideOne(),我将访问局部内部类的成员变量:");
System.out.println("局部内部类的成员变量xx = " + xx + " , " + "局部内部类的成员变量aa = " + aa);
}
}
//定义局部内部类的外部类成员方法访问局部内部类,需要先创建局部内部类对象,才能访问局部内部类成员
InsideClass i = new InsideClass();
i.testInsideOne();
System.out.print("你好!我是定义局部内部类的外部类成员方法testExternalTwo(),我将访问局部内部类的成员变量:");
System.out.println("局部内部类的成员变量xx = " + i.xx + " , " + "局部内部类的成员变量aa = " + i.aa);
}
public static void main(String[] args) {
ExternalClass e = new ExternalClass();
e.testExternalTwo();
}
}
运行结果:
java
你好!我是局部内部类的成员方法testInsideOne(),我将访问外部类的成员变量:外部类成员变量x = 10 , 外部类成员变量a = 你好!我是个外部类的成员变量
你好!我是局部内部类的成员方法testInsideOne(),我将访问外部类的成员方法:你好!我是外部类成员方法:testExternalOne();
你好!我是局部内部类的成员方法testInsideOne(),我将访问定义我的外部类的成员方法的成员变量:定义局部内部类的外部类成员方法的成员变量y = 20 , 定义局部内部类的外部类成员方法的成员变量b = 你好!我是外部类成员方法中的变量
你好!我是局部内部类的成员方法testInsideOne(),我将访问局部内部类的成员变量:局部内部类的成员变量xx = 30 , 局部内部类的成员变量aa = 你好!我是局部内部类的成员变量
你好!我是定义局部内部类的外部类成员方法testExternalTwo(),我将访问局部内部类的成员变量:局部内部类的成员变量xx = 30 , 局部内部类的成员变量aa = 你好!我是局部内部类的成员变量
- 局部内部类访问外部类成员的时候,可以直接访问,定义局部内部类的外部类成员方法访问局部内部类的成员的时候,需要先创建对象,外部类的其它成员方法无法访问局部内部类;
4.静态内部类
定义:
- 静态内部类,就是用static关键字修饰的成员内部类;
- 静态内部类,只能访问外部类的静态成员;
- 上代码
java
public class ExternalClass {// 外部类
// 外部类成员属性
static int x = 10;
static String a = "这是个外部类的静态成员变量";
// 外部类成员方法
public static void testExternalOne() {
System.out.println("这是个外部类的静态成员方法 testExternalOne");
}
public void testExternalTwo() {
InsideClass ins = new InsideClass();
System.out.println("外部类调用静态内部类的成员变量: " + "静态内部类变量 xx = " + ins.xx + " , " + "静态内部类变量 aa = " + ins.aa);
System.out.print("外部类调用静态内部类的成员方法: ");
ins.testInsideOne();
}
// 成员静态内部类
static class InsideClass {// 成员静态内部类
// 静态内部类成员属性
int xx = 20;
String aa = "这是个静态内部类的成员变量";
// 静态内部类成员方法
public void testInsideOne() {
System.out.println("这是个静态内部类的成员方法 testInsideOne");
}
public void testInsideTwo() {
System.out.println("静态内部类调用外部类的静态成员变量: " + "外部类静态变量 x = " + x + " , " + "外部类静态变量 a = " + a);
System.out.print("静态内部类调用外部类的静态成员方法: ");
testExternalOne();
}
}
public static void main(String[] args) {
ExternalClass test0 = new ExternalClass();
test0.testExternalOne();
test0.testExternalTwo();
System.out.println();
ExternalClass.InsideClass test1 = new ExternalClass.InsideClass();
test1.testInsideOne();
test1.testInsideTwo();
}
}
运行结果:
java
这是个外部类的静态成员方法 testExternalOne
外部类调用静态内部类的成员变量: 静态内部类变量 xx = 20 , 静态内部类变量 aa = 这是个静态内部类的成员变量
外部类调用静态内部类的成员方法: 这是个静态内部类的成员方法 testInsideOne
这是个静态内部类的成员方法 testInsideOne
静态内部类调用外部类的静态成员变量: 外部类静态变量 x = 10 , 外部类静态变量 a = 这是个外部类的静态成员变量
静态内部类调用外部类的静态成员方法: 这是个外部类的静态成员方法 testExternalOne
- 创建静态内部类的对象语法:外部类名.静态内部类名 变量名 = new 外部类名.静态内部类名();;
5.匿名内部类
- 匿名内部类,没有名字;
- 用以简化接口参数传递时的代码
- 上代码
java
interface OneInterface {// 创建一个接口
void show();
}
class InterfaceImpl implements OneInterface {
@Override
public void show() {
System.out.println("InterfaceImpl类实现了接口OneInterface");
}
}
class TestInterface {
void test(OneInterface oneInterface) {
System.out.println("这只是一个测试方法");
oneInterface.show();
}
}
public class Test00 {
public static void main(String[] args) {
TestInterface t1 = new TestInterface();
OneInterface o1 = new InterfaceImpl();
t1.test(o1);
System.out.println();
TestInterface t2 = new TestInterface();
t2.test(new OneInterface() {// 创建匿名内部类实例化接口
@Override
public void show() {
System.out.println("匿名内部类实现了接口OneInterface");
}
});
}
}
运行结果:
java
这只是一个测试方法
InterfaceImpl类实现了接口OneInterface
这只是一个测试方法
匿名内部类实现了接口OneInterface
- 如果方法含有接口类参数的时候,无需单独书写实例化接口的类,而只需要通过匿名内部类直接实例化接口就可以了,简化了代码的书写;
- 创建匿名内部类语法:new 父接口() {//匿名内部类实例化接口代码块}
6.总结
- 成员内部类结合接口的使用,解决了Java单继承规则下的,多继承实例应用;
- 局部内部类、静态内部类,更多的是为强化代码的访问范围,主要用于提高代码的安全性;
- 匿名内部类,主要用于简化接口实现代码;