Inner Class
a> 在一个类中定义一个类,这个类就叫做内部类或者内置类(inner class).
b> 内部类可以让我们将逻辑上相关的一组类组织起来,并由外部类(outer class)
来控制内部类的可见性.
c> 当我们建立一个inner class的时候,其对象就拥有了与外部类对象之间的一种关系,
这是通过一个特殊的this inference形成的,使得内部类对象可以随意的访问外部
类中的所有成员。
d> 在内部类中可以访问外部类的私有成员变量,也就是在内部类中可以随意的访问
外部类中的所有的成员方法和变量
e> 可以把内部类放到一个方法中来定义,但是它的使用范围必须是在这个方法里
f> 当我们在一个方法中定义一个内部类时,如果我们需要在方法中内部类去访问这个
本地变量(方法中声明的变量)时,我们必须把这个变量声明为final才行,不然
编译器会报错
eg:
void fn(int final a)
{
if(true)
{
class Middle
{
private int index=70;
class Inner
{
private int index=60;
void print()
{
int index=80;
System.out.println(index); //访问print()方法中的index=80变量
System.out.println(this.index); //访问Inner类的成员变量index=60;
System.out.println(Middle.this.index); //访问Middle类的成员变量index=70;
System.out.println(Outer.this.index); //访问Outer类的成员变量index=100;
}
}
}
}
}
f> 对于Inner类的访问权限我们可以声明为所有的(protected,private,public,default)。
h> 对于内部类来说,如果起访问权限为protected,那么他可以在同一个类被访也可以在同
一个包中被访问。而如果声明为private的那么那只能在Outer这个外部类被访问。我们
可以把它生命为abstract(这个时候不能用Inner直接去实例化一个内部类),我们可以在
外部类中定义一个类,从Inner派生出来,直接实例化。当我们声明为final,那就不能再
派生了,对于内部类来说还可以声明为static,那么这个时候就可以不需要同时存在外部
类的对象,那么这个时候我们也不能访问外部类的非静态的成员变量和方法。相当于切断
了与外部内对象的联系。非静态的内部类不能在内部类本身中定义静态的方法(反之可以)。
非static的内部类中的成员变量不能声明为static的,只在顶层类或static的内部类中可以
声明为static的。
g> 为什么要使用内部类?
1.在内部类(inner class)中可以随意访问外部类中的成员,让我们更好的管理和组织我们
的代码。增强代码的可读性。
2.内部类用于创建适配器类,适配器类是用于实现接口的类,使用内部类来实现接口,可以
更好的定位与接口关联的方法在代码中的位置。
3.其他的用法
a> 我们可以通过把内部类声明为private来隐藏接口的实现细节
b> 我们需要派生一个类,同时又需要去实现一个接口,如果基类中有个方法和接口中的方法
同名,但是他们的用法不一样,我们就可以用内部类来解决。
=============================================================================
内部类的一般用法:
class Outer //Outer class
{
private int index=100; //私有的变量
/*
class Inner //Inner Class,independence individual
{ //可以整体的把Inner类看成是Outer类的一个成员
private int index=50;
void print()
{
int index=30;
System.out.println(index);
System.out.println(this.index);
System.out.println(Outer.this.index);
}
}*/
/*
*Inner类不管嵌套层次有多深,都可以随意的访问外部的成员变量
*当我们在一个方法中定义一个内部类时,如果我们需要在方法中内部类去访问这个
*本地变量(方法中声明的变量)时,我们必须把这个变量声明为final才行,不然
*编译器会报错
void fn(final int a)
{
final int b=1;
if(true)
{
class Middle
{
private int index=70;
class Inner
{
private int index=60;
void print()
{
int index=80;
System.out.println(index); //访问print()方法中的index=80变量
System.out.println(this.index); //访问Inner类的成员变量index=60;
System.out.println(Middle.this.index); //访问Middle类的成员变量index=70;
System.out.println(Outer.this.index); //访问Outer类的成员变量index=100;
System.out.println(a);
System.out.println(b);
}
}
}
}
}
/*
*我们可以把内部类放到一个方法中,但是它的使用范围也定在了这个方法的范围里,甚至可以放到if()块
*代码块中{}中,它告诉我们,不管我们把Inner()嵌套有多深,它都可以随意的访问外部类中的所有成员
void fn()
{
class Inner
{
private int index=50;
void print()
{
int index=30;
System.out.println(index);
System.out.println(this.index);
System.out.println(Outer.this.index);
}
}
}
*/
static class Inner
{
private int index=50;
void print()
{
int index=80;
System.out.println(index); //访问print()方法中的index=80变量
System.out.println(this.index); //访问Inner类的成员变量index=60;
System.out.println(Outer.this.index); //访问Outer类的成员变量index=100;
}
}
void print()
{
//Inner inner=new Inner();
//inner.print();
}
/*
Inner getInner()
{
return new Inner();
}
*/
/*
public static void main(String[] args)
{
Outer outer=new Outer();
//outer.print();
//Inner in=outer.getInner();这是一句错误的代码,因为Inner是定义在Outer类的内部的,所以对外是
//不可见的,这个时候需要我们,使用外部类名来调用
Inner in=outer.getInner(); //因为现在main()方法在Outer类里,这个时候Inner类对于main()方法来说是可见的
Inner in=new Inner();
in.print();
}*/
}
class Test
{
/*public static void main(String[] args)
{
Outer outer=new Outer();
//outer.print();
//Inner in=outer.getInner();这是一句错误的代码,因为Inner是定义在Outer类的内部的,所以对外是
//不可见的,这个时候需要我们,使用外部类名来调用
Outer.Inner in=outer.getInner();
in.print();
}*/
public static void main(String[] args)
{
Outer outer=new Outer();
//outer.print();
//Inner in=outer.getInner();这是一句错误的代码,因为Inner是定义在Outer类的内部的,所以对外是
//不可见的,这个时候需要我们,使用外部类名来调用
//Outer.Inner in=outer.getInner();
Outer.Inner in=outer.new Inner(); //用外部类对象来产生
in.print();
}
}
*****************************************************************************
从内部类派生的用法:
/*
*从内部类派生的用法
*/
class Car
{
class Wheel
{
}
}
class PlaneWheel extends Car.Wheel
{
PlaneWheel(Car car)
{
car.super(); //建立内部类对象到子类的引用
}
public static void main(String[] args)
{
Car car=new Car();
PlaneWheel pw=new PlaneWheel(car);
}
}
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
内部类实现接口:
//用内部类实现接口,接口不能被实例化
interface Animal
{
void eat();
void sleep();
}
class Zoo
{
private class Tiger implements Animal
{
public void eat()
{
System.out.println("Tiger eat!");
}
public void sleep()
{
System.out.println("Tiger sleep!");
}
}
Animal getAnimal()
{
return new Tiger();
}
/*
Animal getAnimal()
{
return new Animal()
{ //这是就是匿名的类
public void eat()
{
System.out.println("Animal eat!");
}
public void sleep()
{
System.out.println("Animal sleep!");
}
}; //这是就是匿名的类
}*/
}
class DoTest
{
public static void main(String[] args)
{
Zoo z=new Zoo();
Animal an=z.getAnimal();
an.eat();
an.sleep();
}
}
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
基类中有个方法和接口中的方法,同名,但是他们的用法不一样:
//基类中有个方法和接口中的方法,同名,但是他们的用法不一样
interface Machine
{
void run();
}
class Person
{
public void run()
{
System.out.println("run");
}
}
class Robot extends Person
{
private class MachineHeart implements Machine
{
public void run()
{
System.out.println("heart run");
}
}
Machine getMachine()
{
return new MachineHeart();
}
}
class Work
{
public static void main(String[] args)
{
Robot robot=new Robot();
Machine m=robot.getMachine();
m.run();
robot.run();
}
}