内部类:
在一个类中再定义一个类,就将定义的那个类称为内部类。内部类可分为成员内部类、局部内部类以及匿名内部类。
1 .成员内部类:
在一个类中使用内部类可以在内部类中直接存取其所在类的私有成员变量。成员内部类的基本语法为:
public class Out{ //外部类
private class inner{ //内部类
//内容
}
}
在内部类中可以随意使用外部类的成员方法以及成员变量,即使这些类成员被修饰为private。
内部类的实例一定要绑定在外部类的实例上,如果在外部类中初始化一个内部类对象,那么内部类对象就会绑定在外部类对象上。内部类初始化方式与其他类初始化方式相同。都是new关键字。
public class Out {
innerClass in = new innerClass(); // 在外部类实例化内部类对象引用
public void ouf() {
in.inf(); // 在外部方法中调用内部类方法
}
class innerClass { // 内部类
innerClass() { // 内部类构造方法
}
int y = 0; // 内部类成员变量
public void inf() { // 内部类成员方法
}
}
public innerClass doit() { // 外部类方法,返回值为内部类引用
// y = 4; //外部类不可以直接访问内部类成员变量
int y = 4;
return new innerClass(); // 返回内部类引用
}
public static void main(String[] args) {
Out out = new Out();
Out.innerClass in = out.doit();
// 内部类的对象实例化操作必须在外部类或外部类中非静态方法中引用
}
}
注:如果在外部类和非静态方法之外是劣化内部类对象,需要使用“外部类.内部类”的形式指定该对象的类型。内部类对象会依赖于外部类对象除非已经存在 一个外部类对象,否则类中不会出现内部类对象。
使用this关键字获取内部类与外部类的引用:
如果在外部类中定义的成员变量与内部类的成员变量名称相同,可以使用this关键字。
public class Out {
private int x;
private class inner {
private int x = 9;
public void doit(int x) {
x++; // 调用的是形参x
this.x++;// 调用内部类的变量x
Out.this.x++;// 调用外部类的变量x
}
}
public static void main(String[] args) {
}
}
2.局部内部类:
局部内部类是指在类的方法中定义的内部类,它的作用范围也是在这个方法体中。
public class Out {
//私有成员变量
private String name;
//构造函数
public Out() {
super();
this.name = "香蕉";
}
//包含内部类的函数
public void sell(int price){
//局部内部类
class Banana{
int innerprice = 0;
//局部内部类构造方法
public Banana(int price) {
super();
this.innerprice = price;
}
//在内部类函数中访问外部成员变量,并调用外部函数。
public void price(){
System.out.println("出售:"+name);
System.out.println("售价:"+innerprice+"元/斤");
}
}
Banana banana = new Banana(price); //实例化banana类的对象
banana.price();//调用局部内部类的方法
}
public static void main(String[] args) {
Out test = new Out();//实例外部类的对象
test.sell(2);//调用外部类的sell()方法
}
}
上面的代码中,内部类定义到sell()方法中,特别注意的一点是,局部内部类是在类方法中定义的类,所以内部类Banana是内部类的一部分,并非Out类的一部分,所以除了sell()方法之外不能访问内部类,但是内部类可以访问外部类的常量和所有成员。
3.匿名内部类
不给内部类取名字,直接以对象名来代替。匿名内部类的所有实现代码都需要在大括号之间进行编写。
语法格式:
return new A(){
........//内部类体
}
由于匿名内部类没有名称,所以匿名内部类使用默认构造方法来生成匿名内部类的对象。在匿名内部类定义结束后,需要加分号标识,这个分号并不代表定义内部类结束的标识,而代表创建匿名内部类的引用表达式的标识。
4.静态内部类
在内部类前添加修饰符static,这个内部类就变为静态内部类。一个静态内部类中可以声明static成员,但是在非静态内部类中不可以声明静态成员。
特点:
不可以使用外部类的非静态成员,所以静态内部类在程序开发中很少见。
创建静态内部类的对象,不需要其外部类的对象。
不能从静态内部类的对象中访问非静态外部类的对象。
public class Out {
static int x = 10;
static class Inner{
static void doitInner(){
System.out.println("外部类的成员变量"+x);//调用外部类的成员变量X
}
public static void main(String[] args) {//静态内部类定义主方法
doitInner();//访问内部类的方法
}
}
}
内部类的继承:
内部类也和其他类一样可以被继承,但是继承内部类比继承其他类要复杂。
public class Out extends ClassA.ClassB { //继承内部类ClassB
public Out(ClassA a) {
a.super();
}
}
class ClassA {
class ClassB {
}
}