- 可以在一个方法里面或者任意的作用域内定义内部类。
- 内部类可以被四个访问权限修饰(public、private、protected、包)。
- 如果想从外部类的非静态方法之外的任意位置创建某个内部类的对象,那么必须具体指明这个对象的类型:OuterClassName.InnerClassName。
public class Test {
class Inner{
public void print() {
System.out.println("11111");
}
}
public void print(){
Inner inner = new Inner();
inner.print();
}
public Inner getInner() {
return new Inner();
}
public static void main(String[] args) {
Test test = new Test();
Inner inner = test.getInner();
inner.print();
test.print();
System.out.println("22222");
}
}
- 内部类拥有外部类所有元素的访问权。
- 当外部类对象创建了一个内部类对象时,此内部类对象必定会秘密地捕获一个指向那个外部类对象的引用。然后当你访问外围类的成员时,就是用那个引用来选择外部类的成员。
- 内部类对象只能在与外部类对象相关联的情况下才能被创建,即在内部类是非static类时,有外部类对象才有内部类对象。
- 一个内部类不管被嵌套了多少层,它都能透明地访问所有它嵌套的外部类的所有成员。0
.this 与.new
- .this用于在内部类中生成对外部类对象的引用。
- .new 用于用外部类对象创建内部类对象。
public class Test {
class Inner{
public Test geTest(){
return Test.this;
}
public void print() {
System.out.println("11111");
}
}
public static void main(String[] args) {
Test test = new Test();
Inner inner = test.new Inner();
inner.print();
}
}
嵌套类
- 如果创建的是嵌套类(静态内部类)那就不需要对外部对象的引用了。
- 不能从嵌套类的对象中访问非静态的外围类对象。
- 还可以在接口内部创建嵌套类,使得嵌套类可以被接口的所有不同实现所共用。
- 普通内部类不能有static数据和static字段,也不能包含嵌套类,但嵌套类可以。
- 还可以使用嵌套类来放置测试代码。
public class Test {
public void print(){
System.out.println("待测试代码");
}
public static class Inner{
public static void main(String[] args){
Test test = new Test();
test.print();
System.out.println("内部类测试代码");
}
}
}
定义在作用域或者方法中的类
public class Test {
public void print(){
class Inner{
public Test geTest(){
return Test.this;
}
public void print() {
System.out.println("11111");
}
}
Inner inner = new Inner();
}
public static void main(String[] args) {
System.out.println("22222");
}
}
匿名内部类
- 匿名内部类用来扩展接口或者类,但是不能两者兼备,最多只能实现一个接口。
- 匿名内部类使用一个在其外部定义的对象,编译器会要求其参数时final的。但是如果不在匿名类内部使用的话,就不要求一定是final的。
public class Test {
public Base getBase(int x){
return new Base(x) {
{System.out.println("匿名内部类实现");}
@Override
public void f() {
System.out.println("匿名内部类方法实现抽象类Base中抽象方法f();");
}
};
}
public static void main(String[] args) {
System.out.println("22222");
}
}
abstract class Base {
public Base(int x) {
System.out.println("Base" + x);
}
public abstract void f();
}