1.什么是内部类?
将一个类A定义在另一个类B里面,里面的那个类A就称为内部类,B则称为外部类。比如汽车是一个类但汽车内部还有发动机类,发动机类就属于内部类。
public class Test {
class Y{
}
}
这段代码中,Test是外部类,Y是内部类
2.特点
1.内部类中的方法可以访问外部类作用域中所有数据(包括私有/private数据)。
2.内部类可以对同一个包中的其他类隐藏起来。
3.在编译过程中,内部类被翻译成”外围类名$内部类名”的一个常规类
4.外部类想要访问内部的成员: 得创建内部类对象来访问内部类成员
格式:
外部类名.内部类名 对象名 = new 外部类名().new 内部类名();
局部内部类
内部类被定义在方法中,和局部变量相同,局部内部类不允许添加任何访问控制符,它的作用域被限定在声明这个局部类的方法(或代码块)中。并且,局部类对外部世界是完全隐藏起来的,及时定义它的方法所在的外部类也不可以访问它。
3.分类
1、根据有无类名分为有名内部类和匿名内部类
public class Test {
class Y{
}
}
这里的Y就属于有名内部类
匿名内部类创建格式:
class 外部类类名{
new 父类构造器([参数列表])|接口(){
匿名内部类类体;
};
}
Mammal mammal = new Mammal() {
@Override
public void move() {
System.out.println("游动");
}
};
要创建匿名内部类必须和实例化同时进行,即:创建匿名内部类必须通过new关键字;
注意:
因为匿名内部类没有名字,所以匿名内部类只能使用一次,它通常用来简化代码
使用匿名内部类的前提条件:必须继承一个父类或实现一个接口
匿名内部类的优点:
以接口举例,当你使用一个接口时,你得做如下几步操作。
1、定义接口的实现类
2、重写接口中的方法
3、创建子类对象
4、调用重写后的方法
但是如果使用匿名内部类就可以将这四步变成一步,简化了代码
2、以有无static关键词修饰分为静态内部类与非静态内部类。
静态内部类形式:
public class Body {
static class Heart{
public void work() {
System.out.println("跳到");
}
};
}
非静态内部类形式:
public class Body {
class Heart{
public void work() {
System.out.println("跳到");
}
};
}
创建内部类对象:
静态内部类:
public class Body {
static class Heart{
public void work() {
System.out.println("跳动");
}
};
public static void main(String[] args) {
Body body = new Body();
Heart heart =new Heart();
heart.work();
}
}
非静态内部类:(需要说明内部类对象属于外部类创建的哪个对象)
public class Body {
class Heart{
public void work() {
System.out.println("跳动");
}
};
public static void main(String[] args) {
Body body = new Body();
Heart heart =body.new Heart();
heart.work();
}
}
访问权限修饰符:
外部类或者接口修饰符只能是public或默认的;
内部类或者接口则四种访问权限都可以,要求内部类或者接口必须像成员变量那样直接定义在外部类中;
局部内部类不允许添加任何访问控制符;
Lambda:jdk8.0+主要用于简化内部类
仅有一个抽象方法的接口称为函数式接口,可以用@FunctionalInterface修饰
只有当实现类的接口为函数式接口时,实现类的匿名内部类才能使用Lambda表达式。
格式:接口名 对象名 = ([参数列表])->返回值
(重写接口的方法体中仅有一行return时,return可以省略)