一、成员内部类
可以访问外部类的所有成员,无论外部类成员是何种权限;
通过外部类访问内部类,则需要通过外部类创建内部类对象;
格式:外部类名 外部类对象 = new 外部类名();
外部类名.内部类名 内部类对象 = 外部类对象.new内部类名();
class Outer{
String str = "@npm";
void shout1(){
System.out.println("外部类成员方法shout1()");
}
//定义成员内部类inner
class Inner{
String sss = "大帅哥";
void show(){
System.out.println("外部类成员str="+str);
shout1();
}
void show2(){
System.out.println("内部类成员方法show2()");
}
}
void shout2(){
Inner inner = new Inner();//实例化内部类对象inner
//访问内部类成员和方法
System.out.println("内部类成员sss="+inner.sss);
inner.show2();
}
}
public class practise {
public static void main(String[] args) {
Outer outer = new Outer();//实例化外部类对象outer
Outer.Inner inner = outer.new Inner();//实例化内部类对象inner
inner.show();//在内部类中访问外部类的成员str和成员方法shout
outer.shout2();//在内部类中访问内部类的成员sss和成员方法show2
}
}
输出结果:
二、局部内部类
也称方法内部类,是指定义在某个局部范围中的类,它和局部变量都是在方法中定义的,有效范围只限于方法内部;
可以访问外部类的所有成员变量和成员方法;
外部类访问内部类的成员,只能在局部内部类所属方法中创建局部内部类的对象,通过对象访问局部内部类的变量和方法。
class Outer{
String str = "@npm";
//定义成员方法shout1()
void shout1(){
System.out.println("外部类成员方法shout()");
}
void shout2(){
//定义一个局部内部类,在局部内部类中访问外部类变量和方法
class Inner{
String sss = "大帅哥";
void show(){
System.out.println("外部类成员str="+str);
shout1();
}
}
//访问局部内部类中的变量和方法
Inner inner = new Inner();
System.out.println("局部内部类sss="+inner.sss);
inner.show();
}
}
public class practise {
public static void main(String[] args) {
Outer outer = new Outer();//实例化外部类对象outer
//通过外部类对象outer调用创建了局部内部类的方法shout2()
outer.shout2();
}
}
输出结果:
三、静态内部类
就是使用static关键字修饰的成员内部类;静态内部类只能访问外部类的静态成员;
通过外部类访问静态内部类成员时,因为程序已经提前在静态常量区为静态内部类分配好了内存,所以即使静态内部类没有加载,依然可以通过外部类之间创建一个静态内部类对象。
基本语法格式:外部类名.静态内部类名 变量名 = new 外部类名.静态内部类名();
class Outer{
static String str = "@npm";
//定义一个静态内部类
static class Inner{
String sss = "大帅哥";
void show(){
//在静态内部类访问外部类的静态成员str
System.out.println("外部类静态成员str="+str);
}
}
}
public class practise {
public static void main(String[] args) {
Outer.Inner inner = new Outer.Inner();
inner.show();
}
}
输出结果:
四、匿名内部类
就是没有名称的内部类;定义匿名内部类时,其类体作为new语句的一部分。
基本语法格式:new 继承的父类或实现的接口名(){匿名内部类的类体}
interface Person{ //定义接口Preson
void shout(); //定义抽象方法 shout()
}
public class practise {
public static void main(String[] args) {
String name = "@npm";
personShout(new Person(){ //调用personShout()方法,参数为匿名内部类
@Override
public void shout(){ //重写了Person接口中的shout()方法
System.out.println(name+"大帅哥");
}
});
}
public static void personShout(Person pr){//该方法参数为Person接口类型
pr.shout();
}
}
运行结果:
在JDK8版本之前,局部变量前必须加final关键字,否则程序编译时报错。但是JDK8版本之后允许在局部内部类、匿名内部类中访问未用final修饰的局部变量。