内部类
在一个类里面定义的类叫内部类,内部类之外的类叫外部类
分为:普通内部类、局部内部类、静态内部类、匿名内部类
成员内部类
成员内部类可以用private、protected、public修饰
成员内部类可以访问外部类的所有成员属性和成员方法(包括private成员和静态成员)当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:外部类.this.成员变量,外部类.this.成员方法
成员内部类不能定义静态变量,静态方法
成员内部类中不能定义静态方法(所以成员内部类中没有main方法)成员内部类是依附外部类而存在的,也就是说,如果要创建成员内部类的对象,前提是必须存在一个外部类的对象
在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问
可以定义成员抽象内部类,抽象内部类的抽象方法不能用private、final、static修饰
静态内部类
静态内部类只能调用外部类的静态方法和静态属性
静态内部类不用产生外部类的实例化对象即可产生内部类的实例化对象
静态内部类也可以用private、protected、public修饰
静态内部类可以定义非静态方法和静态方法,也可以定义静态属性和非静态属性
可以定义静态抽象内部类,静态内部类的抽象方法不能用private、final、static修饰
静态内部类中可以有main()方法并且可以执行
静态内部类与非静态内部类的区别?
1) 是否能拥有静态成员
静态内部类可以有静态成员(方法,属性),而非静态内部类则不能有静态成员(方法,属性)。
2) 访问外部类的成员
静态内部类只能够访问外部类的静态成员,而非静态内部类则可以访问外部类的所有成员(方法,属性)。
3) 静态内部类和非静态内部类在创建时有区别
静态内部类通过外部类的类名实例化,非静态内部类只能通过外部类实例创建
局部内部类
局部内部类和匿名内部类只能访问局部final变量
局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符
方法内部类不能使用访问控制符和 static 修饰符
匿名内部类
匿名内部类也是不能有访问修饰符和static修饰符的,匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以大部分匿名内部类用于接口回调。
一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。
内部类实例
public class OuterClass {
private String name = "YCY";
private static int age = 18;
public void say() {
System.out.println("OuterClass say()");
}
/**
* · 普通内部类
*/
class InnerClass {
// 内部类不能有静态方法和静态变量
// static int number = 100;
// static void test() { }
public void say() {
System.out.println("我的名字:" + name );
System.out.println("我的年龄:" + age);
OuterClass.this.say();
}
}
/**
* · 局部内部类
* · 不加修饰符public private
* · 内部中使用外部方法的局部变量,该局部变量必须是final(JDK1.7有要求,JDK1.8不是必须的)
*/
public void speak() {
String classroom = "004班";
// 局部内部类
class InnerClass{
public void tell() {
System.out.println("我的名字:" + name );
System.out.println("我的年龄:" + age);
System.out.println("我的班级:" + classroom);
}
}
// 调用局部内部类中的方法
new InnerClass().tell();
}
/**
* · 静态内部类
* · 访问外部类成员必须是静态的
* · 静态内部类不可以用 private 来定义
*/
private static String school = "CCIT";
public static class StaticInnerClass {
public void say() {
// 访问外部类成员必须是静态的
// System.out.println("我的名字:" + name );
System.out.println("我的年龄:" + age);
// System.out.println("我的班级:" + classroom);
System.out.println("我的学校:" + school);
}
public static void speak() {
// System.out.println("我的名字:" + name );
System.out.println("我的年龄:" + age);
// System.out.println("我的班级:" + classroom);
System.out.println("我的学校:" + school);
}
}
public static void main(String[] args) {
// 方法一创建普通内部类
OuterClass outerClass = new OuterClass();
OuterClass.InnerClass innerClass02 = outerClass.new InnerClass();
// 方法二创建普通内部类
InnerClass innerClass01 = new OuterClass().new InnerClass();
innerClass01.say();
// 使用局部内部类的
OuterClass outerClass2 = new OuterClass();
outerClass.speak();
// 使用静态内部类的静态方法
OuterClass.StaticInnerClass.speak();
// 使用静态内部类的非静态方法
OuterClass outerClass3 = new OuterClass();
new OuterClass.StaticInnerClass().say();//创建匿名对象调用
/**
* · 匿名内部类
* · 无构造方法,使用有限
* · 使用外部方法中的局部变量,局部变量必须是finnal(JDK1.8 不需要finnal)
* · 匿名内部类中的方法必须是重写外部类的方法,不能调用局部内部类中特有的方法
*/
OuterClass outerClass4 = new OuterClass() {
String sex = "男";
public void say() {
System.out.println("AnonymousClass say()");
System.out.println(sex);
}
public void tell() {
System.out.println("匿名内部类特有方法");
}
};
// 调用局部内部类的方法
outerClass4.say();
// 不能调用局部内部类中特有的方法
// outerClass4.tell();
}
}