目录
什么是内部类?
就是在一个类的内部在定义一个完整的类。
public class Outer{
class Inner{
}
}
上面代码Inner就是一个简单的内部类。
而且,他是可以生成独立的.class文件。
还可以访问外部类的私有成员而不破坏封装。(主要作用)
内部类大致可以分为4种:成员内部类、静态内部类、局部内部类、匿名内部类。
成员内部类:
在类的内部定义,和实例变量、实例方法同级别的类:
package com.classes.demo01;
// 成员内部类
public class Demo01 {
// 实例变量
public String name = "我是一个人";
public int age = 18;
// 内部类
class Student{
// 内部类里无法写静态变量 static
private String name = "我是一个学生";
private int age = 20;
public void show(){
// 如果在内部类要调用外部类的属性,加上前缀 Demo01.this.name;
System.out.println(Demo01.this.name);
// 打印内部类属性
System.out.println(name);
System.out.println(age);
}
}
}
这里特别注意,成员内部类中无法写静态方法。
且当外部类和内部类存在同名属性时,会优先访问内部类属性。所以外部类最好加上前缀:类名.this.属性名。
主方法:
public class Test {
public static void main(String[] args) {
// 成员内部类
// 先创建一个外部类对象
Demo01 person = new Demo01();
// 再用外部类对象来调用成员内部类
Demo01.Student student = person.new Student();
student.show();
System.out.println("==================================");
System.out.println(person.name);
System.out.println(person.age);
}
}
运行结果:
静态内部类:
不依赖外部类对象,可直接通过创建或类名访问,可声明静态成员,它的级别是和外部类相同的。
package com.classes.demo01;
public class Demo02 {
private String name = "这是一个实例变量";
private int age = 18;
// 成员内部类前加上static就是静态内部类 它的级别和外部类相同
static class Inner{
private String address = "上海";
private String phone = "123456";
private static int count = 10000;
public void show(){
// 怎么调用外部类的属性?
// 因为它的级别和另一个外部类相同,所以可以把他当成另一个类来看
// 先创建外部类对象,再调用
Demo02 demo02 = new Demo02();
System.out.println(demo02.name);
System.out.println(demo02.age);
// 调用静态内部类的属性和方法
System.out.println(address);
System.out.println(phone);
// 调用静态内部类的静态属性
System.out.println(Inner.count);
}
}
}
注意点都在代码上。
Test类(主方法):
package com.classes.demo01;
public class Test {
public static void main(String[] args) {
// 静态内部类
// 直接创建静态内部类的对象
Demo02.Inner inner = new Demo02.Inner();
inner.show();
System.out.println("=====================================");
}
}
运行结果:
局部内部类:
它定义在方法中,作用范围和创建对象仅限于方法,就是只能在方法中使用。级别和局部变量相同。
package com.classes.demo01;
//外部类,定义在外部类的方法中
public class Demo03 {
private String name = "郑仲华";
private int age = 20;
public void show(){
// 定义局部变量
String address = "泉州信息工程学院";
// 定义内部类:和局部变量级别相同,不能加任何访问类型的修饰符 public protected private
class Inner{
// 局部类中不能定义静态变量,可以定义静态常量
private final static int count =1000;
private String phone = "1255555555555555555";
private String email = "1500900127@qq.com";
public void show2(){
// 调用外部类的属性
System.out.println(Demo03.this.name);
System.out.println(Demo03.this.age);
// 调用内部类属性
System.out.println(this.phone);
System.out.println(this.email);
// 调用局部变量:jdk1.7之前,变量必须是常量final,jdk1.8之后,自动添加了final
System.out.println(address);//其实真正的代码是这样子的:System.out.println("泉州信息工程学院");
// 为什么是常量,因为在外部类的方法中,如果定义了一个变量,而不是常量,该变量会在外部类方法运行后消失,而内部类不会消失,会导致引用不了。
}
}
// 创建局部变量对象:局部内部类只能在方法中实例化
Inner inner = new Inner();
inner.show2();
}
}
特别注意:
再来看看主方法:
package com.classes.demo01;
public class Test {
public static void main(String[] args) {
// 局部内部类
Demo03 demo03 = new Demo03();
demo03.show();
}
}
要调用内部类,直接访问外部类的方法。反正它是在外部类的方法中定义的 。
运行结果:
还有一点:
调用局部变量也就是外部类方法中的属性时,必须是常量。
至于为什么是常量:
因为在外部类的方法中,如果定义了一个变量,而不是常量,该变量会在外部类方法运行后消失,而内部类不会消失,会导致引用不了。
匿名内部类:
就是没有命名的局部内部类。(一切特征都和内部类相同)
直接看一个经典匿名内部类用法:
先创建一个接口:
Usb:
package com.classes.demo02;
public interface Usb {
void service();
}
Mouse连接接口:
package com.classes.demo02;
public class Mouse implements Usb {
@Override
public void service() {
System.out.println("连接电脑成功,鼠标开始工作了......");
}
}
主方法:
package com.classes.demo02;
public class Test {
public static void main(String[] args) {
// Usb usb = new Mouse();
// usb.service()
// 2.使用匿名内部类优化(相当于创建了一个局部内部类)
// 必须继承一个父类或者接口
Usb usb = new Usb() {
@Override
public void service() {
System.out.println("连接成功,风扇开始运行了......");
}
};
usb.service();
}
}
/*
1.局部内部类只能使用一次,使用匿名内部类优化,如上
class Fan implements Usb{
@Override
public void service() {
System.out.println("连接成功,风扇开始运行了......");
}
}
*/
主方法运行,没啥大问题(上面第一行注释) 。
还可以用局部变量进行接口连接(后面注释)。
最后才是匿名类的主要作用:对局部变量进行优化。
上述方法的使用的前提就是必须继承一个父类或者接口。
这个就是相当于创建了一个局部内部类。就是代码可读性差。