1.成员内部类
即在一个类中直接定义的内部类, 成员内部类与普通的成员没什么区别,可以与普通成员一样进行修饰和限制。成员内部类不能含有static的变量和方法。
注意事项:
1.实例内部类内部不允许定义任何静态内容
2.外部类静态方法中不能访问实例内部类数据
3.如果外部类成员变量、内部类成员变量、内部类方法中局部变量同名
class Cat{//外部类 private double weight; public Cat(double weight) { this.weight = weight; } class CatBody{//内部类 private String color; public CatBody(String color) { this.color = color; } public void show() { //内部类 可以直接访问外部类的成员 Cat.this.weight //内部类中 隐含了 一个外部类对象 Cat.this System.out.println("颜色:"+color+","+weight); } } public void display() { System.out.println("重量:"+weight); //颜色 外部类 访问 内部类的成员 用对象调用 CatBody body = new CatBody("白色"); body.show(); } } public class TestInner1 { public static void main(String[] args) { Cat cat = new Cat(33.3); cat.display(); //必须 用 外部类 对象来 创建 内部类对象,属于 外部类对象的 Cat.CatBody body = cat.new CatBody("黑色"); body.show(); } }
2.局部内部类
在方法中定义的内部类称为局部内部类。与局部变量类似,局部内部类不能有访问说明符,因为它不是外围类的一部分,但是它可以访问当前代码块内的常量,和此外围类所有的成员。
注意事项
1.局部内部类不能声明静态成员
2.局部内部类处于静态方法中只能直接访问外部类静态成员
3.局部内部类处于实例方法中可以直接访问外部类静态成员和实例成员
4.局部内部类对局部变量的访问,JDK8.0之前只能访问final修饰的局部变量,8.0之后可以访问局部变量,但是局部变量的值不允许修改
public class TestInner2 { static int ns = 77; int num = 99; public void f() { final int number = 99;//8.0之前只能访问fianl int number1 = 100; // number1 = 678; class Inner{ //局部内部类 中不能声明静态成员,static final除外 static final int n = 66; public void show() { System.out.println(ns);//直接访问外部类静态成员 System.out.println(num);//直接访问外部类实例成员 System.out.println(number); //8.0之后 可以访问局部变量,但是局部变量的值不允许修改 System.out.println(number1);// } } } public static void fs() { class Inner{ //局部内部类 中不能声明静态成员,static final除外 static final int n = 66; public void show() { System.out.println(ns);//直接访问外部类静态成员 System.out.println(new TestInner2().num);//对象访问 } } } public static void main(String[] args) { // TODO Auto-generated method stub } }
3.静态内部类(嵌套类)
如果你不需要内部类对象与其外围类对象之间有联系,那你可以将内部类声明为static。这通常称为嵌套类(nested class)。想要理解static应用于内部类时的含义,你就必须记住,普通的内部类对象隐含地保存了一个引用,指向创建它的外围类对象。然而,当内部类是static的时,就不是这样了。嵌套类意味着:
1. 要创建嵌套类的对象,并不需要其外围类的对象。
2. 不能从嵌套类的对象中访问非静态的外围类对象。
class School{ static class WaterFountain{ static int water = 56; public static void show() { System.out.println(water); } int water1 = 77; public void show1() { System.out.println(water1); } } public void display() { WaterFountain.show();//静态内部类中的静态成员,通过类名访问 WaterFountain w = new WaterFountain(); w.show1();//访问 非静态的成员 ,用静态内部类对象 调用 } } public class TestStaticInner1 { public static void main(String[] args) { School s = new School(); s.display(); //创建 静态内部类对象 School.WaterFountain w = new School.WaterFountain(); w.show1();//非静态的 w.show();//静态的 School.WaterFountain.show();//静态 } }
4.匿名内部类
匿名内部类就是没有名字的内部类。什么情况下需要使用匿名内部类?如果满足下面的一些条件,使用匿名内部类是比较合适的:
- 只用到类的一个实例。
- 类在定义后马上用到。
- 类非常小(SUN推荐是在4行代码以下)
- 给类命名并不会导致你的代码更容易被理解。
-
class Base{ public void f() { } } /*class Sub extends Base{ public void f() { System.out.println("sub"); } }*/ class Demo{ //成员 Base base1 = new Base() { //不能定义构造方法,但是能定义构造块 { System.out.println("我是一个构造块"); } public void func() {}//自己独特的调用不到 static final int x = 55; public void f() { System.out.println("sub"); } }; public void show() { new Base() { public void f() { System.out.println("sub"); } public void func() {} }.func(); } } public class TestInner1 { public static void main(String[] args) { Demo demo = new Demo(); demo.base1.f(); // demo.base1.func();//调用不到 /*Sub sub = new Sub(); sub.f();*/ //创建的是子类对象 } }