在JAVA编程中,类被定义成一个独立的程序单元。将一个类放在另一个类内部的定义,这个定义在其它类的内部就叫内部类(嵌套类),包含内部类的类也称为外部类(宿主类)。
内部类的作用:
1.内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其它类访问该类。
2.内部类的成员可以直接访问外部类的私有数据,因为内部类被当做外部类成员,同一个类中的成员可以相互访问。
3.匿名内部类适合用于创建那些仅需要使用一次的类。
一般来说,内部类都被作为成员内部类定义,而不是作为局部内部类。成员内部类是一种与成员变量、方法、构造器和初始化块相似的类成员;局部内部类和匿名内部类则不是类成员。

成员内部类
非静态内部类
public class Cow {
private double weight;
public Cow(){}
public Cow(double weight){
this.weight = weight;
}
//定义一个非静态内部类
public class CowLeg{
private double length;
private String color;
public CowLeg(){}
public CowLeg(double length,String color){
this.length = length;
this.color = color;
}
//下面省略setter,getter方法
//非静态内部类的实例方法
public void info(){
System.out.println("当前小牛腿的颜色为:" + color + ",高:" + length );
//直接访问外部类的private修饰的成员变量
System.out.println("本牛腿所在的奶牛重:" + weight);
}
}
public void test(){
CowLeg cowLeg = new CowLeg(1.12,"黑白相间");
cowLeg.info();
}
public static void main(String[] args) {
Cow cow = new Cow(378.9);
cow.test();
}
}
编译上面的程序,看到文件所在的路径生成2个class文件,Cow.class和Cow$CowLeg.class
如果外部类成员变量、内部类成员变量与内部类里方法的局部变量同名,则可以通过this、外部类类名.this
作为限制区分。
public class DiscernVariable {
private String prop = "外部类的实例变量";
private class InClass{
private String prop = "内部类的实例变量";
public void info(){
String prop = "局部变量";
//访问外部类的实例变量
System.out.println(DiscernVariable.this.prop);
//访问内部类的实例变量
System.out.println(this.prop);
//访问局部变量
System.out.println(prop);
}
}
public void test(){
InClass inClass = new InClass();
inClass.info();
}
public static void main(String[] args) {
new DiscernVariable().test();
}
}
静态内部类
使用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);
//下面代码正常,因为prop2是静态成员变量
System.out.println(prop2);
}
}
}
外部类不能直接访问静态内部类的成员,但可以使用静态内部类的类名作为调用者来访问静态内部类的类成员和实例成员,如下代码:
public class StaticInnerClassTest {
static class StaticInnerClass {
private int prop1 = 5;
private static int prop2 = 9;
}
public void accessOuterProp(){
//下面代码有异常,静态类无法访问外部类的实例变量
System.out.println(prop2);
//可以使用内部类.成员变量的方法访问
System.out.println(StaticInnerClass.prop2);
//下面代码正常,通过实例访问静态内部类的实例变量
System.out.println(new StaticInnerClass().prop1);
}
}
局部内部类
如果将一个内部类定义在一个方法体内,则这个内部类就是一个局部内部类,仅在方法体内有效。由于局部内部类不能在外部类的方法体以外的地方使用,因此局部内部类也不能访问控制符和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 = 8;
is.b = 9;
System.out.println("Inner对象的a和b实例变量是:" + is.a + "," + is.b);
}
}
编译上诉代码,可以看到生成3个class文件:LocalInnerClass .class 、 LocalInnerClass$1InnerBase .class、LocalInnerClass$1InnerSub .class
这表明局部内部类的命名规则总是遵循如下命名格式:
OutterClass$NInnerClass.class
Java8改进的匿名内部类
关于匿名内部类的2条规则:
1.匿名内部类不能是抽象类
2.匿名内部类不能定义构造器,因为匿名内部类没有类名,但可以定义初始化块
interface Product{
public double getPrice();
public String getName();
}
public class AnonymouseTest {
public void test(Product p){
System.out.println("购买了一个" + p.getName() + ",花掉了" + p.getPrice());
}
public static void main(String[] args) {
AnonymouseTest ta = new AnonymouseTest();
//此处调用匿名实现类的实例
ta.test(new Product() {
@Override
public double getPrice() {
return 576.2;
}
@Override
public String getName() {
return "AGP显卡";
}
});
}
}
程序媛小白一枚,如有错误,烦请批评指正!(#.#)
网友评论