内部类,顾名思义,就是在一个类的内部再定义一个类,这个类就叫做内部类。
比如,在class A中再定义一个class B,则B是A的内部类,A是B的外部类。
内部类可以分为以下四类:
Outer.java文件内定义内部类
public class Outer {
private int id;
public void out(){
System.out.println("这是外部类方法");
}
public class Inner{
public void in(){
System.out.println("这是内部类的方法");
}
}
}
Test.java来实例化一个内部类
成员内部类需要先创建外部类的对象,再创建内部类的对象
public class Test{
public static void main(String[] args){
//第一种写法
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
//第二种写法
//Outer.Inner inner = new Outer().new Inner();
}
}
内部类可以获取外部类的私有属性、方法,格式是:外部类名.this
2.2 静态内部类(由static修饰的内部类)
在静态内部类里可以直接访问外部类的静态成员,但不能直接访问外部类的实例成员(必须用外部类的对象进行访问)
Outer.java文件
public class Outer{
//静态内部类
public static class Inner{
private String name;
public static int a;
public void test(){
}
public String getName(){
return name;
}
public void setName(String name){
this.name = name;
}
}
}
Test.java文件
public class Test{
public static void main(String[] args){
Outer.Inner in = new Outer.Inner();
in.test();
}
}
2.3 局部内部类
public class Outer{
public void method(){
class Inner{
public void in(){
}
}
}
}
2.4 匿名内部类
为什么叫匿名?因为不需要为这个类声明名字,用于更方便的创建子类对象。
举例:
public class Test{
public static void main(String[] args){
Animal a = new Cat();
a.cry();//输出喵喵喵
}
}
class Cat extends Animal{
@Override
public void cry(){
System.out.println("喵喵喵");
}
}
abstract class Animal{
public abstract void cry();
}
上面是按照以前的正常写法,需要new出对象后再进行调用
使用匿名内部类的代码
匿名内部类本质就是一个子类,会立即创建出一个子类对象
public class Test{
public static void main(String[] args){
//把这个匿名内部类编译成一个子类,然后创建出一个子类对象
Animal a = new Animal(){
@Override
public void cry(){
System.out.println("喵喵喵");
}
};
a.cry();//输出喵喵喵
}
}
abstract class Animal{
public abstract void cry();
}
匿名内部类使用场景
匿名内部类通常作为一个参数传输给方法
public class Test2{
public static void main(String[] args){
//之前的写法
// Swimming s1 = new Swimming(){
// @Override
// public void swim(){
// System.out.println("狗游的飞快");
// }
// };
// go(s1);
// }
//简化写法
go(Swimming s1 = new Swimming(){
@Override
public void swim(){
System.out.println("狗游的飞快");
}
};);
//可以再简化一点
//go(new Swimming(){
//@Override
//public void swim(){
//System.out.println("狗游的飞快");
//}
//};);
//设计一个方法,可以接受Swimming接口的一切实现类对象
public static void go(Swimming s){
System.out.println("开始~~~~~~");
s.swim();
}
}
//设置一个接口,猫和狗都参加游泳比赛
interface Swimming{
void swim();
}
当然,再简化就变成了lambda表达式,这里就不具体介绍了。