内部类
什么是内部类? 定义在一个类里面的类就叫内部类,相对而言包含内部类的类就叫外部类
//外部类
class Outer{
//内部类(在类的内部定义一个类)
class Inner{
}
}
内部类的特点:
- 编译之后可生成独立的字节码文件。
- 内部类可直接访问外部类的私有成员,而不破坏封装。
- 可为外部类提供必要的内部功能组件。
内部类可以分为 --> 成员内部类、静态内部类、局部内部类、匿名内部类。
成员内部类
-
在类的内部定义,与实例变量、实例方法同级别的类(这个“级别”指的是访问的级别)
//外部类 class Outer2{ //实例变量 private String name = "张三"; //方法 public void show(){ } //成员内部类 class Inner2{ } }
-
与实例变量、实例方法一样,想要使用成员内部类,就必须先创建外部类对象,由外部类对象来创建内部类对象,即成员内部类对象的创建必须依赖外部类的对象
-
当外部类、内部类存在重名属性时,会优先访问内部类属性。
-
成员内部类不能定义静态成员。
public class Demo02 { public static void main(String[] args) { // //先创建外部类对象 // Outer2 outer2 = new Outer2(); // //再创建内部类对象 // Outer2.Inner2 inner2 = outer2.new Inner2(); //一步创建内部类对象 Outer2.Inner2 inner2 = new Outer2().new Inner2(); inner2.show(); } } //外部类 class Outer2{ //实例变量 private String name = "张三"; private int age = 10; //成员内部类 class Inner2{ private String address = "北京"; private String phone = "123412"; // private static int age = 10; 内部类中不能定义静态变量 private static final int years = 10; //但是可以定义静态常量。 //如果内部类属性与外部类属性重名,优先输出内部类属性 private String name = "李四"; //内部类方法 void show(){ //输出外部类的属性 //与内部类属性重名时,使用 [外部类名.this.属性] 来区分属性 System.out.println(Outer2.this.name); //也可以直接访问外部类属性(没有重名属性) System.out.println(age); //输出内部类的属性 System.out.println(this.address); System.out.println(this.phone); } } }
静态内部类(很少使用)
静态内部类即在成员内部类前加static关键字
//外部类
class Outer3{
//静态内部类,它的级别和外部类相同
static class Inner3{ //注意:static只能修饰内部类,不可以修饰外部类。
}
}
- 不依赖外部类对象,可直接创建或通过类名访问,可声明静态成员。
- 只能直接访问外部类的静态成员(实例成员实例化外部类对象)。
public class Demo03 {
public static void main(String[] args) {
//创建静态内部类对象
Outer3.Inner3 inner3 = new Outer3.Inner3();
inner3.show();
}
}
//外部类
class Outer3{
private String name = "张三";
private int age = 10;
//静态内部类,它的级别和外部类相同
static class Inner3{ //注意:static只能修饰内部类,不可以修饰外部类。
private String address = "上海";
private String phone = "234";
public static int year = 123; //可以定义静态变量
void show(){
//静态内部类调用外部类属性时,和其他类调用外部类属性一样要创建对象
Outer3 outer3 = new Outer3();
//输出外部类的属性
System.out.println(outer3.name);
System.out.println(outer3.age);
//输出内部类属性
System.out.println(this.address);
System.out.println(this.phone);
}
}
}
局部内部类
定义在外部类方法中,作用范围和创建对象范围仅限于当前方法。
//外部类
class Outer4{
private int age = 35;
void show(){
//局部内部类:定义在方法的内部
class Inner{
}
}
}
- 局部内部类访问外部类当前方法中的局部变量时,因无法保障变量的生命周期与自身相同,变量必须修饰为final。有兴趣可以了解一下方法的生命周期和垃圾回收机制。
- 限制类的使用范围。局部内部类只能在当前方法中使用。
public class Demo04 {
public static void main(String[] args) {
//创建外部对象
Outer4 outer = new Outer4();
outer.show();
}
}
//外部类
class Outer4 {
private String name = "张三";
private int age = 35;
void show() {
//定义局部变量
final String address = "上海";
//局部内部类:不能加任何访问修饰符
class Inner {
//局部内部类的属性
private String phone = "242343";
//不能定义静态变量,可以定义静态常量
// private static int count = 134;
private final static int count = 123;
public void show2() {
//访问外部类的属性
System.out.println(Outer4.this.name);
//访问内部类的属性
System.out.println(this.phone);
//访问局部变量,jdk1.7要求,变量必须时常量final,jdk1.8自动添加final。
System.out.println(address);//这里实际放的是常量 "上海"。
}
}
//如果局部内部类里使用了局部变量,则变量不可被修改了。
//思考:如果show()方法消失了,Inner类会立即消失吗?show2()方法会消失吗?
//如果address是变量可行吗?
// address = "12312";
//创建局部类对象
Inner inner = new Inner();
inner.show2();
}
}
匿名内部类
匿名内部类在内部类中使用最频繁,它有以下几个特点
- 没有类名的局部内部类(一切特征都与局部内部类相同)。
- 必须继承一个父类或者实现一个接口。
- 定义类、实现类.创建对象的语法合并,只能创建一个该类的对象。
//定义一个接口
public interface Usb {
//服务
void service();
}
public class Demo05 {
public static void main(String[] args) {
//局部内部类
// class Fan implements Usb{
// @Override
// public void service() {
// System.out.println("链接电脑。");
// }
// }
//使用局部内类创建对象
// USB usb = new Fan();//多态的使用
// usb.service();
//使用匿名内部类优化,实现了Usb接口
Usb usb = new Usb(){//相当于创建了一个局部内部类
//内部实现了Usb内的方法
@Override
public void service() {
System.out.println("链接电脑。");
}
};//注意:加了分号
usb.service();
}
}
优点:减少代码量.(有一些类可能只使用一次,没必要创建单独的一个类)
缺点:可读性较差。
ps:以上是本人学习内部类的笔记和一些个人的思考,对内部类做了一个简单的介绍,对于有些问题没有做深入的解释(自己也不是很懂ヽ(*。>Д<)o゜)。希望对你有所帮助。