一.内部类基础
在Java中,可以将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类。广泛意义上的内部类一般来说包括这四种:成员内部类、局部内部类、匿名内部类和静态内部类。下面就先来了解一下这四种内部类的用法。
1.成员内部类
成员内部类是最普通的内部类,它的定义为位于另一个类的内部,形如下面的形式:
class Circle {
double radius = 0;
public Circle(double radius) {
this.radius = radius;
}
class Draw { //内部类
public void drawSahpe() {
System.out.println("drawshape");
}
}
}
这样,Draw类看起来就像Circle类的成员,Circle类被称为外部类。成员内部类无条件访问外部类的所有成员属性和成员方法(包括私有和静态)。
class Circle {
private double radius = 0;
public static int count =1;
public Circle(double radius) {
this.radius = radius;
}
class Draw { //内部类
public void drawSahpe() {
System.out.println(radius); //外部类的private成员
System.out.println(count); //外部类的静态成员
}
}
}
但是请注意,当内部成员类的成员变量或方法与外部类的名称相同时,就会发生隐藏,这意味着内部类的成员在默认情况下被访问。如果你想访问具有相同名称的外部类的成员,你需要以以下形式访问它:
外部类.this.成员变量
外部类.this.成员方法
内部类的成员可以无条件地访问外部类的成员,而外部类却不能如此自由地访问内部类的成员。要访问外部类中的内部类的成员,必须首先创建内部类的对象,然后通过对象的引用访问它:
class Circle {
private double radius = 0;
public Circle(double radius) {
this.radius = radius;
getDrawInstance().drawSahpe(); //必须先创建成员内部类的对象,再进行访问
}
private Draw getDrawInstance() {
return new Draw();
}
class Draw { //内部类
public void drawSahpe() {
System.out.println(radius); //外部类的private成员
}
}
}
内部成员类依赖于外部类,也就是说,如果要创建内部成员类的对象,则必须存在外部类的对象。创建成员内部类对象的一般方法如下:
public class Test {
public static void main(String[] args) {
//第一种方式:
Outter outter = new Outter();
Outter.Inner inner = outter.new Inner(); //必须通过Outter对象来创建
//第二种方式:
Outter.Inner inner1 = outter.getInnerInstance();
}
}
class Outter {
private Inner inner = null;
public Outter() {
}
public Inner getInnerInstance() {
if(inner == null)
inner = new Inner();
return inner;
}
class Inner {
public Inner() {
}
}
}
2.局部内部类
局部内部类是定义在一个方法或者一个作用域里面的类,它和成员内部类的区别在于局部内部类的访问仅限于方法内或者该作用域内。
class People{
public People() {
}
}
class Man{
public Man(){
}
public People getWoman(){
class Woman extends People{ //局部内部类
int age =0;
}
return new Woman();
}
}
请注意,局部内部类,就像方法中的局部变量一样,不能有公共、受保护、私有或静态修饰符。
匿名内部类
匿名内部类可能是我们在编写代码时使用最多的类。在编写监听事件的代码时使用匿名内部类不仅方便,而且使代码更易于维护。下面的代码是一个Android事件监听器:
scan_bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
history_bt.setOnClickListener(new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
});
这段代码为两个按钮设置监听器,这里面就使用了匿名内部类。这段代码中的:
new OnClickListener() {
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
这就是匿名内部类的使用。代码需要为按钮设置一个侦听器对象。使用匿名内部类可以在父类或接口中实现方法时生成相应的对象,但前提是父类或接口首先存在。当然,下面也是可能的,像上面一样使用匿名内部类来达到同样的效果。
private void setListener()
{
scan_bt.setOnClickListener(new Listener1());
history_bt.setOnClickListener(new Listener2());
}
class Listener1 implements View.OnClickListener{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
class Listener2 implements View.OnClickListener{
@Override
public void onClick(View v) {
// TODO Auto-generated method stub
}
}
4.静态内部类
静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象。
public class Test {
public static void main(String[] args) {
Outter.Inner inner = new Outter.Inner();
}
}
class Outter {
public Outter() {
}
static class Inner {
public Inner() {
}
}
}

本文详细讲解Java内部类的四种类型:成员内部类、局部内部类、匿名内部类和静态内部类,涉及访问权限、实例化方法及应用场景实例。

被折叠的 条评论
为什么被折叠?



