内部类的分类
内部类的分类
成员内部类、静态内部类、局部内部类、匿名内部类
什么是内部类
概念:在一个类的内部再定义一个完整的类
public class body01 {
class Header{
//内部类也会生产一个 .class文件夹,但是命名时外部加内部共同命名
}
}
特点:
-
编译之后可以生成独立的字节码文件
-
内部类可直接访问外部类的私有成员,而不破坏封装。
public class body01 { private String name; class Header{ public void show(){ System.out.println(name); } } }
-
可为外部类提供必要的内部功能组件.
成员内部类
- 在类的内部定义,与实例变量、实例方法同级别的类
- 外部类的一个实例部分,创建内部类对象时,必须依赖外部类对象.
- Outer out = new Outer();
- Inner inner = new Inner();
package com.java.ar;
import com.java.ar.Outer.Inner;
public class Test {
public static void main(String[] args) {
//1创建外部类
//Outer outer = new Outer();
//2创建内部类
//Inner inner = Outer.new Inner();
//一步结局的
Outer.Inner inner1 = new Outer().new Inner();
inner1.show();
}
}
package com.java.ar;
public class Outer {
//实例变量
private String name ="阿娆" ;
private int age = 20;
//内部类
class Inner {
private String address="njupt";
private int grade = 3;
public void print(){
//外部类
System.out.println(name);
System.out.println(age);
//内部类
System.out.println(address);
System.out.println(grade);
}
public void show() {
print();
}
}
}
输出:
阿娆
20
njupt
3
- 当外部类、内部类存在重名属性时,会优先访问内部类属性
package com.java.ar;
public class Outer {
//实例变量
private String name ="阿娆" ;
private int age = 20;
//内部类
class Inner {
private String address="njupt";
private int grade = 3;
private String name = "阿娆划水";
public void print(){
//外部类
System.out.println(name);
System.out.println(age);
//内部类
System.out.println(address);
System.out.println(grade);
}
public void show() {
print();
}
}
}
输出:
阿娆划水 /* 在内部类中添加了一个也叫name的,先访问的是内部类中的name*/
20
njupt
3
若是需要调用外部类的相同命名属性,需要Outer.this.name来访问
- 成员内部类不能是静态成员,但是可以有静态常量
静态内部类
- 不依赖外部对象,可直接创建或通过类名访问,可声明静态成员
package com.ar.chapter1;
public class Outer {
private String name ="阿娆" ;
private int age = 20;
//静态内部类,和外部类相同
static class Inner{
private String address="njupt";
private int grade = 3;
//可以包括静态成员
private static String name1 = "阿娆划水";
public void show(){
//如何调用 不能直接调用了,需要实例化才能调用
//System.out.println(name);
//1先创建外部类对象
Outer outer = new Outer();
//2调用外部类对象的属性
System.out.println(outer.name);
//调用静态内部类的可直接调用,因为就是她自己de
System.out.println(name1);
//调用静态内部类的静态属性
System.out.println(Inner.name1);
}
}
}
package com.ar.chapter1;
public class Test {
public static void main(String[] args) {
//直接创建静态内部类对象,不少Outer
Outer.Inner inner = new Outer.Inner();
//调用方法
inner.show();
}
}
局部内部类
- 定义在外部类方法中,作用范围和创建对象范围仅限于当前方法
package com.ar.chapter0;
public class Outer {
private String name ="阿娆" ;
private int age = 20;
public void show(){
//局部变量
String address = "nj";
//局部内部类:主要不能加任何访问修饰符
class Inner{
//局部内部类
private String grade = "3";
private String shool = "njupt";
public void show2(){
//访问外部类的属性,一下两个表达内容一样
System.out.println(age);
System.out.println(Outer.this.age);
//访问内部类属性
System.out.println(grade);
System.out.println(shool);
}
}
//创建局部内部类对象
Inner inner = new Inner();
inner.show2();
}
}
package com.ar.chapter0;
public class Test {
public static void main(String[] args) {
Outer outer = new Outer();
//直接调用没有输出,因为局部的不能在其他地方用,需要在局部内部类内部去写对象
outer.show();
}
}
- 局部内部类访问外部类当前方法中的局部变量时,因无法保证变量的生命周期与自身相同,变量必须修饰为finall(jdk1.7,1.8会自动修饰)
- 限制类的使用范围只能在当前的类中使用
匿名内部类
- 没有类名的局部内部类(特征与局部内部类相同)
- 必须继承一个父类,或实现一个接口
- 定义类、实现类、创建对象的语法合并,只能创建一个该类的对象
- 优点:减少代码量
- 缺点:可读性较差
package com.ar.chapter3;
public class Test {
public static void main(String[] args) {
//创建接口变量
USB usb = new Mouse();
usb.service();
//局部内部类
class nujpt implements USB{
@Override
public void service() {
System.out.println("开学啦");
}
}
//使用局部内部类创建对象
USB usb1 = new nujpt();
usb1.service();
}
}
package com.ar.chapter3;
public class Mouse implements USB{
@Override
public void service() {
System.out.println("连接成功");
}
}
package com.ar.chapter3;
public interface USB {
void service();
}
输出
连接成功
开学啦
-
使用内部类的优化
USB usb = new USB{ @Override public void service() { System.out.println("开学啦"); } }; usb.service();