内部类的分类:成员内部类(静态,非静态),局部内部类(方法内,代码块内,构造器内)
1. 成员内部类
-
作为外部类的成员
- 调用外部类的结构
- 可以被static修饰
- 可以被4种不同的权限修饰
-
作为一个类
- 类内可以定义属性,方法,构造器等
- 可以被final修饰,表示此类不能被继承
- 可以被abstract修饰
public class Person {
String name;
int age;
public void sayHello(){
System.out.println("Person");
}
// 静态成员内部类
static class Dog{
String name;
int age;
public Dog(){}
{}
static {}
}
// 非静态成员内部类
class Bird{
String name;
public void sing(){
sayHello();// 相当于Person.this.sayHello()
}
public void display(String name){
System.out.println(name);// 形参
System.out.println(this.name);// 内部类属性
System.out.println(Person.this.name);// 外部类属性
}
}
public void method(){
// 局部内部类
class AA{
}
}
{
// 局部内部类
class BB{
}
}
public Person(){
// 局部内部类
class CC{
}
}
}
public class test {
public static void main(String[] args) {
// 实例化静态成员内部类
Person.Dog dog = new Person.Dog();
// 实例化非静态成员内部类
Person p = new Person();
Person.Bird bird = p.new Bird();
}
}
2. 局部内部类
public class testInner {
public Comparable getComparable(){
// 方式一:
class MyComparable implements Comparable{
@Override
public int compareTo(Object o) {
return 0;
}
}
//return new MyComparablejava();
// 方式二:
return new Comparable() {
@Override
public int compareTo(Object o) {
return 0;
}
};
}
}
非静态内部类中不能有静态变量,静态方法和静态代码块,但是可以有静态常量。在类加载的时候,静态属性和代码块会先加载,那么按照这个逻辑,非静态内部类里面的静态属性也要优先于这个内部类加载,但这个时候这个内部类都还没有初始化,这就出现矛盾了。而常量之所以可以(不论有无static),因为java在编译期就确定所有常量,放到所谓的常量池当中。
public Person(){
int num = 10;// 默认为final
// 局部内部类
class CC{
public void show(){
//num = 10;// 不可修改
System.out.println(num);
}
}
}
在局部内部类中,如果调用局部内部类所声明的方法中的局部变量,要求此局部变量声明为final的。
- jdk 7 及以前版本,要求此局部变量显示的声明为final的
- jdk 8 及之后的版本,可以省略final的声明
类A如何继承类B中的非静态成员内部类?
3. 匿名内部类与Lambda
public class test01 {
public static void main(String[] args) {
// 局部内部类
class Like1 implements ILike{
@Override
public void lambda(int a, int b) {
System.out.println("1");
}
}
ILike like = new Like1();
like.lambda(1, 1);
// 匿名内部类,没有类名,必须借助接口或父类
ILike like1 = new ILike() {
@Override
public void lambda(int a, int b) {
System.out.println("2");
}
};
like.lambda(2, 2);
// 用lambda简化,必须依赖函数式接口即一个接口只能有一个方法
ILike like2 = (a, b) -> {
System.out.println("3");
};
like.lambda(3, 3);
}
}
interface ILike{
void lambda(int a, int b);
}