内部类
内部类的定义
将一个类定义在另一个类的里面,对于里面那个类就称为内部类(内置类,嵌套类)。
例如:如果在类Outer的内部再定义一个类Inner,此时Inner就称为Outer的内部类,而Outer则称为Inner的外部类。
内部类语法格式
标识符 class 外部类的名称{
//外部类的成员
标识符 class 内部类的名称{
//内部类的成员
}
}
内部类的分类
- 成员内部类
1、 成员内部类也称为实例内部类。
2、 成员内部类内不能声明静态变量和静态方法,但是可以定义静态常量。
3、 成员内部类持有外部类的对象,即先有外部类对象才可以创建内部类对象。
4、 在文件管理方面,成员内部类在编译完成后也会产生.class文件,而文件名称则是”外部类名称$内部类名称.class”
5、 在外部创建内部类对象的方法:
Outer outer = new Outer(); //创建外部类对象
Outer.Inner inner = outer.new Inner(); //先有外部类对象才可以创建内部类对象。
InnerClassDemo.java
public class InnerClassDemo {
public static void main(String[] args) {
OutClass oc = new OutClass();
OutClass.InnerClass inner = oc.new InnerClass();
inner.fun();
inner.fun1();
}
}
OutClass.java
public class OutClass {
private int a;
public void fun() {
System.out.println("外部类fun方法");
}
public void fun2() {
System.out.println("外部类fun2");
}
public class InnerClass {
private int b;
public void fun() {
System.out.println(a);
System.out.println("内部类fun方法");
}
public void fun1() {
// 就近原则
fun();// 内部类fun
fun2();// 外部类fun2
// 内部类访问外部类的方法OutClass.this.fun();
OutClass.this.fun();// 外部类fun
}
}
}
- 静态内部类
1、 如果一个内部类使用static声明,则此内部类就称为静态内部类。
2、 访问静态内部使用 外部类名.内部类名
3、 创建静态内部类对象时,不必持有外部类对象,可以直接创建内部类对象。
Outter.Inner inner = new Outter.Inner(); //直接创建内部类对象 Outer.new Inner();//错误
Outer.java
public class Outer {
private int a;
public static class Inter {
public void fun() {
// System.out.println(a);静态不能访问非静态,不能访问外部类
System.out.println("静态内部类的fun方法");
}
}
}
OuterDemo.java
public class OuterDemo {
public static void main(String[] args) {
// new Outer().new Inter();非静态内部类的创建(需要对象)
// new Outer.Inter();静态内部类的创建
Outer.Inter inter = new Outer.Inter();
inter.fun();
}
}
- 匿名内部类
如果一个内部类在整个操作中只使用一次的话,就可以定义为匿名内部类
匿名内部类,这是java为了方便我们编写程序而设计的一个机制,因为有时候有的内部类只需要创建一个它的对象就可以了,以后再不会用到这个类,这时候使用匿名内部类就比较合适
匿名类内部不用声明类名称,而是用new直接产生一个对象。匿名内部类是在抽象类和接口的基础上发展起来的。它可以是继承某个类,或是实现某个接口。
比如:可以直接继承Object类定义一个匿名类,在重写toString方法后,用匿名类直接产生一个对象。
在文件管理方面,内嵌匿名类编译后生成的.class文件的命名方式是”外部类名称$编号.class”,编号为1,2,3…n,编号为x的文件对应的就是第x个匿名类
定义一个接口,里面有个play方法
IInterface.java
public interface IInterface {
void play();
}
Main.java
public class Main {
public static void main(String[] args) {
new IInterface() {
@Override
public void play() {
System.out.println("play");
}
}.play();
fun(new IInterface() {
@Override
public void play() {
System.out.println("play2");
}
});
}
public static void fun(IInterface iInterface) {
iInterface.play();
}
}
使用匿名内部类比较字符串
Demo2.java
public class Demo2 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("x");
list.add("d");
list.add("z");
list.add("a");
list.add("b");
list.add("c");
Collections.sort(list, new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return o2.compareTo(o1);
}
});
System.out.println(list);
}
}
- 局部内部类(基本不用)
1、 局部内部类也叫内嵌内部类、方法内部类
2、 局部内部类是定义在方法内的内部类,它的作用域只是该方法内,只能在该方法内部使用。所以局部内部类同方法内的局部变量一样,不能添加任何修饰符。
3、 局部内部类不能包含静态成员
JBClass.java
public class JBClass {
public static void main(String[] args) {
int a = 10;
class Inner {
int a = 20;
public void fun() {
System.out.println("局部内部类fun方法");
}
}
Inner inner = new Inner();
inner.fun();
}
}