1 内部类
内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的类。对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现outer.class和outer$inner.class两类。所以内部类的成员变量/方法名可以和外部类的相同。
1.1 成员内部类
成员内部类是外部类的成员,可以直接使用外部类的成员和方法,即使是private。
外部类要访问内部类的所有成员变量/方法,则需要通过内部类的对象来获取。
成员内部类不能含有static的变量和方法。因为成员内部类需要先创建了外部类,才能创建它自己的。
在成员内部类要引用外部类对象时,使用outer.this来表示外部类对象;
创建内部类对象,可以使用outer.inner obj = outerobj.new inner();
public class Outer {
public class Inner {
public void print(String str) {
System.out.println(str);
}
}
public Inner getInner() {
return new Inner();
}
}
1.2 局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。
class People{
public People() {
}
}
class Man{
public Man(){
}
public People getWoman(){
class Woman extends People{ //局部内部类
int age =0;
}
return new Woman();
}
}
局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。
1.3 静态内部类
静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法。
class Outter {
public Outter() {
System.out.println("Outter constructor.");
}
static class Inner {
public Inner() {
System.out.println("Inner constructor.");
}
}
}
1.4 匿名内部类
不使用匿名内部类的情况
abstract class Person {
public abstract void eat();
}
class Child extends Person {
public void eat() {
System.out.println("eat something");
}
}
public class Demo {
public static void main(String[] args) {
Person p = new Child();
p.eat();
}
}
使用匿名内部类的情况
abstract class Person {
public abstract void eat();
}
public class Demo {
public static void main(String[] args) {
Person p = new Person() {
public void eat() {
System.out.println("eat something");
}
};
p.eat();
}
}
使用匿名内部类的好处:就拿多线程来说,当我们使用匿名内部类就可以大大减少我们类的个数,举例:
public class Demo {
public static void main(String[] args) {
Thread t = new Thread() {
public void run() {
for (int i = 1; i <= 5; i++) {
System.out.print(i + " ");
}
}
};
t.start();
}
}
如果不采用这个方式就需要实现一个类使之实现Runnable接口并重写run()方法(增加类个数)。
非静态内部类和静态内部类区别
- 静态内部类可以不依赖与外部类实例被实例化,非静态内部类需要在外部类被实例化后才能被实例化。
- 局部内部类不能直接访问外部类的成员,除非是静态内部类访问外部类的静态成员。
- 静态内部类可以有静态成员,非静态内部类不能有静态成员。
- 非静态内部类的非静态成员可以访问外部类的非静态变量。