/*<<java学习笔记>>读后思
内部类(内嵌类)入门
author:shine
*/
概念:在类中还可以再定义类,称之为内部类(Inner Class)或内嵌类(Nested Class)。内部类的主要目的,就是对外隐藏类的存在性。种类(4种):
1. 成员内嵌类(Member Inner Class)
它基本上就是指在一个类中直接声明另一个类。
exp1:
//PointDemo.java
package com.shine.innerClass;public class PointDemo {
private String prompt = "使用了所属类的私有变量"; private void hello() {
System.out.println("使用了所属类的私有方法");
} // 内部类
private class Point {
private int x, y; public Point() {
System.out.println(prompt);
hello();
} public void setPoint(int x, int y) {
this.x = x;
this.y = y;
} public int getX() {
return x;
} public int getY() {
return y;
}
} public Point[] points;
public PointDemo(int length) {
points = new Point[length];
for (int i = 0; i < points.length; i++) {
points[i] = new Point();
points[i].setPoint(i * 5, i * 5);
}
} public void showPoints() {
for (int i = 0; i < points.length; i++) {
System.out.printf("Point[%d]: x = %d, y = %d%n", i, points[i]
.getX(), points[i].getY());
}
}
}//测试:
package com.shine.innerClass;public class PointShow {
public static void main(String[] args) {
PointDemo demo = new PointDemo(5);
demo.showPoints();
}
}
输出结果:
使用了所属类的私有变量
使用了所属类的私有方法
使用了所属类的私有变量
使用了所属类的私有方法
使用了所属类的私有变量
使用了所属类的私有方法
使用了所属类的私有变量
使用了所属类的私有方法
使用了所属类的私有变量
使用了所属类的私有方法
Point[0]: x = 0, y = 0
Point[1]: x = 5, y = 5
Point[2]: x = 10, y = 10
Point[3]: x = 15, y = 15
Point[4]: x = 20, y = 20
小结:
> 内部类可以使用所属类的的私有成员变量(包括属性和方法)。
> 内部类的作用域只在所属类内部。
................................................................................................................................................................................
2. 区域内嵌类(Local Inner Class)
内部类除了可以嵌入到“类成员”中,甚至可以嵌入到“方法”中,这就是Local Inner Class
exp2:
//LocalInnerDemo.java
package com.shine.innerClass;public class LocalInnerDemo {
private String prompt = "使用了所属类的私有变量"; private void hello() {
System.out.println("使用了所属类的私有方法");
}
public void show() {
final String prompt2 = "使用了所属方法的局部变量";
class LocalInner {
public LocalInner() {
System.out.println(prompt2);
System.out.println(prompt);
hello();
}
}
new LocalInner();
}
}//测试
package com.shine.innerClass;public class LocalInnerTest {
public static void main(String[] args) {
LocalInnerDemo demo = new LocalInnerDemo();
demo.show();
}
}
输出结果:
使用了所属方法的局部变量
使用了所属类的私有变量
使用了所属类的私有方法
小结:
> Local Inner Class 可以使用所属类的私有成员变量(包括属性和方法)。
> Local Inner Class 还可以使用所属方法的局部变量,前提是该局部变量有final修饰符。
> Local Inner Class 不同于Member Inner Class ,它不能有类修饰符,否则报错。
> Local Inner Class 的作用域只在所属方法中。
> 看一下产生的.class文件就会发现,区域内部类和成员内部类的命名规范一样:外部类名称$内嵌类名称.class 如:
LocalInnerDemo$1LocalInner.class
................................................................................................................................................................................
3. 匿名内部类(Anonymous Inner Class)
顾名思义:一个没有名字的内部类。
语法格式:
1)new [接口()] {
//内部类实现指定接口(必须实现该接口的方法);
}exp3:
//先定义一个接口 IHello,java
package com.shine.innerClass;public interface IHello {
public void hello();
}//定义匿名内部类 Hello.java
package com.shine.innerClass;public class Hello {
public static void main(String[] args) {
IHello hello = new IHello() {
//实现IHello接口中的hello方法
public void hello() {
System.out.println("hello world");
}
};
hello.hello();
}
}
输出结果:
hello world
2)
new [类()] {
//内部类继承指定类(可以重写指定类中的方法)
}exp4:
package com.shine.innerClass;public class AnonymousClassDemo {
public static void main(String[] args) {
final int x = 10;
Object obj = new Object() {
//重写Object的toString 方法
//int x = 10;
public String toString() {
// TODO Auto-generated method stub
return x + "";
}
};
System.out.println(obj.toString());
}
}
输出结果:
10
小结:
> 如果匿名类的所属类带参数,如:
Class1 obj = new Class1(param){
//内部类实现
}
相当于:
....
super(param);
//内部类实现
....
由此看来,内部类实际上只是所属类的一种扩展(实现接口或重写方法),就算新增一个方法,它的作用域也无法超出“内部”。
> exp4中,匿名内部类可以使用所属方法的局部变量x,前提是该变量必须有final修饰。为什么不让改变局部变量x的值呢?原因在于局部变量x并不是
真正被拿来在内部类中使用,x会被复制到内部类中作为内部类的成员变量,由于内部类使用的只是x的复制品,即使对x的复制品做任何变化,也不会
影响到原来的x,所以java中干脆就不让你改x了,修饰符final由此而来。
> 看一下产生的.class文件就会发现,匿名内部类的命名规范:外部类名称$编号.class 如:Hello$1.class
................................................................................................................................................................................
4.静态内部类(Static Inner Class)
这是最后一个Inner Class,顾名思义:它由static 来修饰。
exp5:
//StaticInnerClass.java
package com.shine.innerClass;public class StaticInnerClass {
private static String i = "外部静态变量i";
private String j = "外部非静态变量j";
public void hello() {
System.out.println("外部非静态方法hello");
}
public static void hello2() {
System.out.println("外部静态方法hello2");
}
static class Inner{
public static String k = "内部类静态变量k";
public String w = "内部类非静态变量w";
public static void innerMethod1() {
System.out.println("内部类静态方法innerMethod1");
//不能调用非静态外部变量System.out.println(j);
System.out.println(i);
//不能调用非静态外部方法hello();
hello2();
} public void innerMethod2() {
System.out.println("内部类非静态方法innerMethod2");
//不能调用非静态外部变量System.out.println(j);
System.out.println(i);
//不能调用非静态外部方法hello();
hello2();
}
}
public void test() {
//调用内部类的成员变量和方法
System.out.println(Inner.k);
Inner.innerMethod1();
}
}//测试:
package com.shine.innerClass;public class Test {
public static void main(String[] args) {
//生成内部类实例test
StaticInnerClass.Inner test = new StaticInnerClass.Inner();
//调用内部类中的静态方法innerMethod1
StaticInnerClass.Inner.innerMethod1();
//调用内部类中的非静态方法innerMethod2
test.innerMethod2();
}
}
输出结果:
内部类静态方法innerMethod1
外部静态变量i
外部静态方法hello2
内部类非静态方法innerMethod2
外部静态变量i
外部静态方法hello2
小结:
> 静态内部类和普通的内部类最大的区别在于:普通的内部类中实际上存在一个外部类的引用this,当我们在内部类中使用外部类的成员变量时实际上
都是以 “this.成员变量” 方式调用的,只不过有时可能省略了this;而静态的内部类中没有了对外部类的引用(this),所以静态内部类不能调用外部
类的非静态的成员变量(包括方法和属性),但外部的静态方法只需要通过类名调用,所以自然静态内部类只能调用外部的静态成员变量了。
................................................................................................................................................................................
2008-4-5