内部类
内部类具有更好的封装手段,可以将其隐藏在外部类之内,更好的实现了信息隐藏,不允许其他类随意的访问
分类
- 成员内部类
- 静态内部类
- 方法内部类
- 匿名内部类
成员内部类
成员内部类是最常见的,也称为普通内部类
- 内部类,在外部使用时,无法直接实例化,需要借由外部类信息才能完成实例化
- 内部类的访问修饰符可以任意,但是访问范围会受到影响
- 内部类可以直接访问外部类的成员;如果出现同名属性,优先访问内部类中定义的
- 可以使用
外部类
.this
.成员
的方式,访问外部类中同名的信息- 外部类访问内部类信息,需要通过内部类实例,无法直接访问
- 内部类编译后,class文件命名:
外部类$内部类.class
public class Person {
public int age = 18;
public Heart getHeart() {
return new Heart();
}
public void eat() {
System.out.println("吃");
}
class Heart{
int age = 12;
public String beat() {
eat();
// 此处age,会有优先访问内部类中定义的
return age + "岁的心扑通扑通的跳," + getPersonAge() + "的心在燃烧";
}
public int getPersonAge() {
// 通过外部类.this.成员的方式访问的Person内的成员变量
return Person.this.age;
}
}
}
Person p = new Person();
p.age = 20;
// 方式一
Person.Heart heart = new Person().new Heart();
System.out.println(heart.beat());
// 方式二
heart = p.new Heart();
System.out.println(heart.beat());
// 方式三
System.out.println(p.getHeart().beat());
打印输出
吃
12岁的心扑通扑通的跳,18的心在燃烧
吃
12岁的心扑通扑通的跳,20的心在燃烧
吃
12岁的心扑通扑通的跳,20的心在燃烧
静态内部类
静态内部类是内部类中一个比较特殊的情况,Java文档中是这样描述static内部类的:一旦内部类使用
static
修饰,那么此时这个内部类就升级为顶级类。
- 静态内部类中,只能直接访问外部类的静态成员,如果需要调用非静态成员,可以通过对象实例调用
- 静态内部类对象实例时,可以不依赖外部类对象
- 可以通过
外部类
.内部类
.静态成员
的方式,访问内部类的静态成员- 内部类可以直接访问外部类的成员;如果出现同名属性,优先访问内部类中定义的
- 如果需要访问外部类中的静态成员,可以使用
外部类
.成员
的方式,访问外部类中同名的信息- 如果是访问非静态成员,则可以使用
new 外部类()
.成员
的方式
public class Person {
public int age = 18;
static String sex = "男";
public Heart getHeart() {
return new Heart();
}
public void eat() {
System.out.println("吃");
}
static class Heart{
int age = 12;
public String beat() {
new Person().eat();
return age + "岁的"+ getPersonSex() +"生心扑通扑通的跳," + getPersonAge() + "的心在燃烧";
}
public static void say() {
System.out.println("hello");
}
public int getPersonAge() {
// 访问非静态属性使用new 外部类().属性
return new Person().age;
}
public String getPersonSex() {
// 访问静态属性用外部类.属性
return Person.sex;
}
}
}
// 静态内部类对象实例时,可以不依赖外部类对象
Person.Heart heart = new Person. Heart();
System.out.println(heart.beat());
// 可以通过外部类.内部类.静态成员的方式,访问内部类的静态成员
Person.Heart.say();
方法内部类
定义在外部类方法中的内部类,也成局部内部类
- 方法内定义的局部变量只能在方法内使用
- 方法内不能定义静态成员
class
前面不可添加public
、private
、protected
、static
- 类中可以包含
final
、abstract
修饰成员
public class Person {
public int age = 18;
// 方法内部类
public Object getHeart() {
class Heart{
int age = 12;
public String beat() {
return age + "岁的生心扑通扑通的跳," + getPersonAge() + "的心在燃烧";
}
public void say() {
System.out.println("hello");
}
public int getPersonAge() {
return new Person().age;
}
}
return new Heart().beat();
}
public void eat() {
System.out.println("吃");
}
}
匿名内部类
将类的定义与类的创建一起完成,可用于简化对于抽象类和接口实现的操作,既然是匿名类,所以无法在别的地方使用这个类(实例化,调用它的静态方法之类的)而且使用频率只能使用一次
特点
- 因此对内存的损耗下相对较小
- 匿名内部类没有类型名称、实例对象名称
- 编译后的文件命名:
外部类$数字序号.class
- 无法使用访问修饰符
private
、public
、protected
、abstract
、static
修饰 - 无法编写构造方法,可以使用构造代码块
- 不能创建静态成员
- 匿名内部类可以实现接口也可以继承父类,但不可兼得
Person
类
public abstract class Person {
private String name;
public Person() {}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public abstract void read();
}
匿名内部类
// 匿名内部类
new Person() {
{
// 构造代码块
}
@Override
public void read() {
// TODO Auto-generated method stub
System.out.println("看武侠");
}
}.read();
适用场景
- 只用到类的一个实例
- 类在定义后马上用到
- 给类命名并不会导致代码更容易被解释