内部类分类
内部类分为成员内部类、局部内部类、匿名内部类和静态内部类。
1.成员内部类
成员内部类像成员变量和成员方法一样,定义在类的内部,成员内部类可以无条件访问外部类的成员变量和成员方法,并且不受外部类的限定符的影响,即外部类的private和static的成员变量和方法都可以访问。示例代码如下:
package renchaofeng_InnerClass;
public class Circle {//外部类
private double radius = 0.0;
public static int count = 1;
public Circle(double radius) {
this.radius = radius;
}
class Draw{//内部类
public void drawShape() {
System.out.println("radius值为:"+radius);
System.out.println("count值为:"+count);
}
}
}
//测试类
package renchaofeng_InnerClass;
import org.junit.Test;
import renchaofeng_InnerClass.Circle.Draw;
public class TestMain {
@Test
public void test() {
Circle c = new Circle(1.2);
Circle.Draw d = c.new Draw();
d.drawShape();
}
}
输出结果为:
radius值为:1.2
count值为:1
这两个值都是外部类的成员变量值。
当内部类中存在和外部类相同的变量时,内部类变量会覆盖隐藏外部类的相同变量,内部类输出结果为自己的变量的值,示例代码如下:
package renchaofeng_InnerClass;
public class Circle {
private double radius = 0.0;
public static int count = 1;
public Circle(double radius) {
this.radius = radius;
}
class Draw{
private double radius = 5.5;//与外部类相同的变量名radius
public void drawShape() {
System.out.println("radius值为:"+radius);
System.out.println("count值为:"+count);
}
}
}
//测试类
package renchaofeng_InnerClass;
import org.junit.Test;
import renchaofeng_InnerClass.Circle.Draw;
public class TestMain {
@Test
public void test() {
Circle c = new Circle(1.2);
Circle.Draw d = c.new Draw();
d.drawShape();
}
}
输出结果为:
radius值为:5.5 //内部类自身的变量值而不是外部类的1.2
count值为:1
如果想在内部类中访问外部类的相同变量,可以用 外部类.this.变量名(外部类.this.方法名)的形式进行访问,如下:
package renchaofeng_InnerClass;
public class Circle {
private double radius = 0.0;
public static int count = 1;
public Circle(double radius) {
this.radius = radius;
}
class Draw{
private double radius = 5.5;
public void drawShape() {
System.out.println("radius值为:"+radius);
System.out.println("count值为:"+count);
System.out.println("外部类的radius值为:"+Circle.this.radius);//访问外部类的radius变量
}
}
}
输出结果为:
radius值为:5.5//内部类的radius值
count值为:1
外部类的radius值为:1.2//外部类的radius值
在外部类中想要访问内部类的变量和方法,就要创建内部类的对象进行访问.
成员内部类中不能存在static变量和方法,因为jvm加载外部类时并不加载成员内部类,成员内部类中如果有static变量和方法就不会加载,既然不会加载就不能使用static变量和方法。成员内部类依附外部类,只有先创建外部类才能创建内部类。
2. 局部内部类
定义在外部类方法里或者作用域里的内部类。局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。示例如下:
public class Parcel5 {
public Destionation destionation(String str){
class PDestionation implements Destionation{
private String label;
private PDestionation(String whereTo){
label = whereTo;
}
public String readLabel(){
return label;
}
}
return new PDestionation(str);
}
public static void main(String[] args) {
Parcel5 parcel5 = new Parcel5();
Destionation d = parcel5.destionation("chenssy");
}
}
3.匿名内部类
匿名内部类顾名思义就是没有名字的内部类,没有名字也就没有构造器。此多用于监听事件场景。匿名内部类基本用于接口回调,匿名内部类没有任何访问修饰符。一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。
示例如下:
public class OuterClass {
public InnerClass getInnerClass(final int num,String str2){
return new InnerClass(){//匿名内部类实现下面的InnerClass接口
int number = num + 3;
public int getNumber(){
return number;
}
}; /* 注意:分号不能省 */
}
public static void main(String[] args) {
OuterClass out = new OuterClass();
InnerClass inner = out.getInnerClass(2, "chenssy");
System.out.println(inner.getNumber());
}
}
interface InnerClass {//此接口用于匿名内部类实现的
int getNumber();
}
输出结果: 5
4. 静态内部类
静态内部类前面带有static修饰符的且不依赖外部类的内部类,静态内部类不能访问外部类的非static成员变量和方法(因为外部类不存在时可以生产静态内部类,假如能调用外部类的非static方法或变量时,外部类不存在就没有对象,没有外部类对象怎么调用非static成员变量或方法)。非静态内部类在编译完成之后会隐含地保存着一个引用,该引用是指向创建它的外部类,但是静态内部类却没有这个引用。示例如下:
public class OuterClass {
private String sex;
public static String name = "chenssy";
/**
*静态内部类
*/
static class InnerClass1{
/* 在静态内部类中可以存在静态成员 */
public static String _name1 = "chenssy_static";
public void display(){
/*
* 静态内部类只能访问外围类的静态成员变量和方法
* 不能访问外围类的非静态成员变量和方法
*/
System.out.println("OutClass name :" + name);
}
}
/**
* 非静态内部类
*/
class InnerClass2{
/* 非静态内部类中不能存在静态成员 */
public String _name2 = "chenssy_inner";
/* 非静态内部类中可以调用外围类的任何成员,不管是静态的还是非静态的 */
public void display(){
System.out.println("OuterClass name:" + name);
}
}
/**
* @desc 外围类方法
* @author chenssy
* @data 2013-10-25
* @return void
*/
public void display(){
/* 外围类访问静态内部类:内部类. */
System.out.println(InnerClass1._name1);
/* 静态内部类 可以直接创建实例不需要依赖于外围类 */
new InnerClass1().display();
/* 非静态内部的创建需要依赖于外围类 */
OuterClass.InnerClass2 inner2 = new OuterClass().new InnerClass2();
/* 方位非静态内部类的成员需要使用非静态内部类的实例 */
System.out.println(inner2._name2);
inner2.display();
}
public static void main(String[] args) {
OuterClass outer = new OuterClass();
outer.display();
}
}
----------------
Output:
chenssy_static
OutClass name :chenssy
chenssy_inner
OuterClass name:chenssy