1.非静态内部类
2.静态内部类(static修饰)
内部类可以比外部类多三个修饰符:private,protected,static——外部类不可以使用这三个修饰符。
非静态内部类是可以访问 外部类成员变量的,因为在编译时,非静态内部类要访问某个变量,系统优先在方法内查找,找不到就去该方法所在内部类找,还找不到就去外部类找,知道在外部类找到了,如果该变量不存在就会编译错误。
如果外部类和内部类有成员变量同名
可以用this, 如 外部类Name.this.变量名
内部类的变量: this.变量名
非静态的内部类可以访问外部类private成员,但是反过来不成立,就是外部类不能访问内部类成员
如果外部类想要访问非静态内类成员,必须显式创建非静态内部类对象来调用其成员。
如下;
public class Outer
{
private int outProp = 9;
class Inner
{
private int inProp = 5;
public void acessOuterProp()
{
// 非静态内部类可以直接访问外部类的private成员变量
System.out.println(“外部类的outProp值:”+ outProp);
}
}
public void accessInnerProp()
{
// 外部类不能直接访问非静态内部类的实例变量,
// 下面代码出现编译错误
// System.out.println(“内部类的inProp值:” + inProp);
// 如需访问内部类的实例变量,必须显式创建内部类对象
System.out.println(“内部类的inProp值:”+ new Inner().inProp);
}
public static void main(String[] args)
{
// 执行下面代码,只创建了外部类对象,还未创建内部类对象
Outer out = new Outer(); //①
out.accessInnerProp();
}
}
同样,外部类的静态方法不能访问非静态内部类(所有静态都不能访问非静态呀)
如下:
public class StaticTest
{
// 定义一个非静态的内部类,是一个空类
private class In{}
// 外部类的静态方法
public static void main(String[] args)
{
// 下面代码引发编译异常,因为静态成员(main()方法)
// 无法访问非静态成员(In类)
new In();
}
}
java不容许 非静态内部类里定义静态成员,(非静态类里面不容许有静态声明)如下:
public class InnerNoStatic
{
private class InnerClass
{
/*
下面三个静态声明都将引发如下编译错误:
非静态内部类不能有静态声明
*/
static
{
System.out.println(“==========”);
}
private static int inProp;
private static void test(){}
}
}
静态内部类:static修饰的内部方法
static修饰的方法属于外部类本身,而不属于外部类的某个对象。
静态内部类不能访问外部实例变量,只能访问静态成员变量(static修饰的成员变量,也成类变量)。
public class StaticInnerClassTest
{
private int prop1 = 5;
private static int prop2 = 9;
//静态内部类
static class StaticInnerClass
{
// 静态内部类里可以包含静态成员
private static int age;
public void accessOuterProp()
{
// 下面代码出现错误:
// 静态内部类无法访问外部类的实例变量
System.out.println(prop1);
// 下面代码正常
System.out.println(prop2);
}
}
}
外部类依旧不能直接访问静态内部类的成员,但可以向上面一样调度,如下:
public class AccessStaticInnerClass
{
static class StaticInnerClass
{
private static int prop1 = 5; //类成员
private int prop2 = 9; //实例成员
}
public void accessInnerProp()
{
// System.out.println(prop1);
// 上面代码出现错误,应改为如下形式:
// 通过类名访问静态内部类的类成员
System.out.println(StaticInnerClass.prop1);
// System.out.println(prop2);
// 上面代码出现错误,应改为如下形式:
// 通过实例访问静态内部类的实例成员
System.out.println(new StaticInnerClass().prop2);
}
}
内部类的使用:
在外部类以外的地方创建非静态内部类实例必须使用外部类实例和new来调用非静态内部类的构造器。如下
//out外部类
class Out
{
//非静态内部类
class In
{
//in方法
public In(String msg)
{
System.out.println(msg);
}
}
}
public class CreateInnerInstance
{
public static void main(String[] args)
{
Out.In a = new Out().new In(“测试信息”); //前面in是类名,后面in是构造器
/*
上面代码可改为如下三行代码:
使用OutterClass.InnerClass的形式定义内部类变量
Out.In a;
创建外部类实例,非静态内部类实例将寄存在该实例中
Out b = new Out();
通过外部类实例和new来调用内部类构造器创建非静态内部类实例
a = b.new In(“测试信息”);
*/
}
}
非静态内部类的构造器必须通过外部类对象调用
子类继承内部类:
public class SubClass extends Out.In
{
//显示定义SubClass的构造器
public SubClass(Out out)
{
//通过传入的Out对象显式调用In的构造器
out.super(“hello”);
}
}
如上表示:SubClass继承了OUT类的内部类in类。
通过外部类对象out, super表示调用In类的构造器,
局部内部类:
在方法内定义内部类,就是局部内部类,局部内部类不能再外部类以外的地方使用,因此局部内部类不能用访问控制符和static修饰。
如下:
public class LocalInnerClass
{
public static void main(String[] args)
{
// 定义局部内部类
class InnerBase
{
int a;
}
// 定义局部内部类的子类
class InnerSub extends InnerBase
{
int b;
}
// 创建局部内部类的对象
InnerSub is = new InnerSub();
is.a = 5;
is.b = 8;
System.out.println(“InnerSub对象的a和b实例变量是:”
+ is.a + “,” + is.b);
}
}
java8中改进的匿名类
interface Product
{
public double getPrice();
public String getName();
}
public class AnonymousTest
{
public void test(Product p)
{
System.out.println(“购买了一个” + p.getName()
+ “,花掉了” + p.getPrice());
}
public static void main(String[] args)
{
AnonymousTest ta = new AnonymousTest();
// 调用test()方法时,需要传入一个Product参数,
// 此处传入其匿名实现类的实例
ta.test(new Product()
{
public double getPrice()
{
return 567.8;
}
public String getName()
{
return “AGP显卡”;
}
});
}
}
还有:
abstract class Device
{
private String name;
public abstract double getPrice();
public Device(){}
public Device(String name)
{
this.name = name;
}
// 此处省略了name的setter和getter方法
public void setName(String name)
{
this.name = name;
}
public String getName()
{
return this.name;
}
}
public class AnonymousInner
{
public void test(Device d)
{
System.out.println(“购买了一个” + d.getName()
+ “,花掉了” + d.getPrice());
}
public static void main(String[] args)
{
AnonymousInner ai = new AnonymousInner();
// 调用有参数的构造器创建Device匿名实现类的对象
ai.test(new Device(“电子示波器”)
{
public double getPrice()
{
return 67.8;
}
});
// 调用无参数的构造器创建Device匿名实现类的对象
Device d = new Device()
{
// 初始化块
{
System.out.println(“匿名内部类的初始化块…”);
}
// 实现抽象方法
public double getPrice()
{
return 56.2;
}
// 重写父类的实例方法
public String getName()
{
return “键盘”;
}
};
ai.test(d);
}
}