内部类
是指在一个外部类的内部再定义一个类。当描述事物时,事物的内部还有事物,该事物用内部类来描述。因为内部事务在使用外部事物的内容。
如同一个人是由大脑、肢体、器官等身体结果组成,而内部类相当于其中的某个器官之一,例如心脏:它也有自己的属性和行为(血液、跳动)。显然,此处不能单方面用属性或者方法表示一个心脏,而需要一个类。而心脏又在人体当中,正如同是内部类在外部内当中。
内部类
将相关的类组织在一起,从而降低了命名空间的混乱。
一个内部类可以定义在另一个类里,可以定义在函数里,甚至可以作为一个表达式的一部分。
Java中的内部类共分为四种:
静态内部类:最简单的内部类形式。类定义时加上static关键字。不能和外部类有相同的名字。被编译成一个完全独立的.class文件,名称为OuterClass$InnerClass.class的形式。只可以访问外部类的静态成员和静态方法,包括了私有的静态成员和方法。
成员内部类:成员内部类也是定义在另一个类中,但是定义时不用static修饰。成员内部类和静态内部类可以类比为非静态的成员变量和静态的成员变量。员内部类就像一个实例变量。它可以访问它的外部类的所有成员变量和方法,不管是静态的还是非静态的都可以。在外部类里面创建成员内部类的实例:this.new Innerclass();在外部类之外创建内部类的实例:(new Outerclass()).new Innerclass();
局部内部类:局部内部类定义在方法中,比方法的范围还小。是内部类中最少用到的一种类型。像局部变量一样,不能被public, protected, private和static修饰。只能访问方法中定义的final类型的局部变量。局部内部类在方法中定义,所以只能在方法中使用,即只能在方法当中生成局部内部类的实例并且调用其方法。
匿名内部类:匿名内部类就是没有名字的局部内部类,不使用关键字class, extends, implements, 没有构造方法。匿名内部类隐式地继承了一个父类或者实现了一个接口。匿名内部类使用得比较多,通常是作为一个方法参数。
为什么要使用内部类?
因为内部类可以随意使用外部类的成员变量(包括私有)而不用生成外部类的对象,这也是内部类的唯一优点
如同心脏可以直接访问身体的血液,而不是通过医生来抽血
内部类的访问规则:
1,内部类可以直接访问外部类中的成员,包括私有。
之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式 外部类名.this
2,外部类要访问内部类,必须建立内部类对象。
访问格式:
1,当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中。
可以直接建立内部类对象。
格式
外部类名.内部类名 变量名 = 外部类对象.内部类对象;
Outer.Inner in = new Outer().new Inner();
2,当内部类在成员位置上,就可以被成员修饰符所修饰。
比如,private:将内部类在外部类中进行封装。
static:内部类就具备static的特性。
当内部类被static修饰后,只能直接访问外部类中的static成员。出现了访问局限。
在外部其他类中,如何直接访问static内部类的非静态成员呢?
new Outer.Inner().function();
在外部其他类中,如何直接访问static内部类的静态成员呢?
outer.Inner.function();
注意:当内部类中定义了静态成员,该内部类必须是static的。
当外部类中的静态方法访问内部类时,内部类也必须是static的。
定义内部类示例:
class Outer
{
private int x = 3;
class Inner//内部类
{
int x = 4;
void function()
{
int x = 6;
System.out.println("innner-function :"+x);
System.out.println("innner :"+this.x);
System.out.println("outer :"+Outer.this.x);
}
}
void method()
{
Inner in = new Inner();
in.function();
}
}
class Test
{
public static void main(String[] args)
{
Outer out = new Outer();
out.method();
Outer.Inner i=out.new Inner();
i.function();
Outer.Inner in=new Outer().new Inner();
in.function();
}
}
匿名内部类:
1,匿名内部类其实就是内部类的简写格式。
2,定义匿名内部类的前提:
内部类必须是继承一个类或者实现接口。
3,匿名内部类的格式: new 父类或者接口(){定义子类的内容}
4,其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖。 可以理解为带内容的对象。
5,匿名内部类中定义的方法最好不要超过3个。
示例:
abstract class AbsDemo
{
abstract void show();
}
class Outer
{
public void function()
{
new AbsDemo()
{
void show()
{
System.out.println("匿名内部类");
}
}.show();
}
}
class Test
{
public static void main(String[] args)
{
new Outer().function();
}
}