内部类是指在一个外部类的内部再定义一个类。类名不需要和文件夹相同。内部类可以是静态static的,也可以是非static的,可用public,default,protected和private修饰。(而外部顶级类即类名和文件名相同的只能使用public和default)。
那么为什么要使用内部类呢?
使用内部类最吸引人的原因是:每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。其实使用内部类最大的优点就在于它能够非常好的解决多重继承的问题。
注意:内部类是一个编译时的概念,一旦编译成功,就会成为完全不同的两类。对于一个名为outer的外部类和其内部定义的名为inner的内部类。编译完成后出现outer.class和outer$inner.class两类。所以内部类的成员变量/方法名可以和外部类的相同。
成员内部类
成员内部类,就是作为外部类的成员,可以直接使用外部类的所有成员和方法。(即使是private修饰的)
注意:
1、外部类要访问内部类的成员变量和成员方法时,则需要通过内部类的对象来获取。
2、成员内部类不能含有static的变量和方法。因为成员内部类需要先创建了外部类,才能创建它自己的。
3、在成员内部类要引用外部类对象时,使用outer.this来表示外部类对象;
为什么成员内部类不能含有static成员变量和方法呢?因为非static的内部类,在外部类加载的时候,并不会加载它,所以它里面不能有静态变量或者静态方法。
1、static类型的属性和方法,在类加载的时候就会存在于内存中。
2、要使用某个类的static属性或者方法,那么这个类必须要加载到jvm中。
基于以上两点,可以看出,如果一个非static的内部类如果具有static的属性或者方法,那么就会出现一种情况:内部类未加载,但是却试图在内存中创建static的属性和方法,这当然是错误的。原因:类还不存在,但却希望操作它的属性和方法。
以上是我个人的理解和看法
package Test04;
public class OuterClass1 {
private String name="Jack";
public static int age=20;
public class InnerClass1{
//public static int salary=100;这一句有问题
public void show(){
System.out.println(name);
System.out.println(age);
}
}
public InnerClass1 getInnerClass1(){
return new InnerClass1();//建议使用getXXX方法来获取成员内部类对象,尤其是该内部类的构造方法无参时
}
public static void main(String[] args) {
OuterClass1 outerclass1=new OuterClass1();
OuterClass1.InnerClass1 innerclass1 = outerclass1.new InnerClass1();
innerclass1.show();
InnerClass1 innerclass2 = outerclass1.getInnerClass1();
innerclass2.show();
}
}
结果为:
Jack
20
Jack
20
局部内部类
局部内部类,是指内部类定义在方法和作用域内
静态内部类(嵌套内部类)
嵌套内部类,就是修饰为static的内部类。声明为static的内部类,不需要内部类对象和外部类对象之间的联系,就是说我们可以直接引用outer.inner,即不需要创建外部类,也不需要创建内部类。
嵌套类和普通的内部类还有一个区别:普通内部类不能有static数据和static属性,也不能包含嵌套类,但嵌套类可以。而嵌套类不建议声明为private,一般声明为public,方便调用。
package Test04;
public class OuterClass {
private String sex="男";
public static String name="chenssy";
static class InnerClass1{
public static String _name1="chenssy_static";//静态内部类可以存在静态成员
private int age=20;//静态内部类中也可以有非静态成员
public void display(){//内部内的成员变量和方法可以和外部类相同
//静态内部类只能访问外围类的静态成员变量和方法
//不能访问外围类中的非静态成员变量和方法
System.out.println("OuterClass name:"+name);
//System.out.println("OuterClass sex:"+sex);这一句不对
}
public static void show(){
System.out.println("不用创建对象,直接调用!");
}
}
class InnerClass2{
public String _name2="chenssy_inner";
//非静态内部类中不能存在静态成员
//private static String salary;这一句不对
public void display(){
//非静态内部类中可以调用外围类的任何成员,不管是静态的还是非静态的
System.out.println("OuterClass name:"+name);
System.out.println("OuterClass sex:"+sex);
}
}
public void display(){
System.out.println(InnerClass1._name1);
new InnerClass1().display();//静态内部类可以直接创建实例,不依赖外围类
//非静态内部类创建实例依赖外围类
OuterClass.InnerClass2 inner2 = new OuterClass().new InnerClass2();
System.out.println(inner2._name2);
inner2.display();
}
public static void show(){
InnerClass1.show();
}
public static void main(String[] args) {
OuterClass outer=new OuterClass();
outer.display();
OuterClass.show();
OuterClass.InnerClass1.show();
}
}
结果为:
chenssy_static
OuterClass name:chenssy
chenssy_inner
OuterClass name:chenssy
OuterClass sex:男
不用创建对象,直接调用!
不用创建对象,直接调用!
匿名内部类
即没有名字的内部类。
参考内部类