java中内部类的使用

内部类是定义在另一个类中的类,内部类的作用如下:

1.内部类方法可以访问外围类的成员,包括私有数据而不用生成外部类的对象

主要原因是内部类和外部类存在逻辑上的关系:

第一:内部类对象的创建依赖于外部类对象(除了静态内部类)

第二:内部类对象持有指向外部类对象的引用

2.内部类可以很好的实现隐藏,普通类不允许有private和protect权限,而内部类可以

3.当想要定义一个回调函数而不想写大量代码时,用匿名内部类比较简洁

内部类主要包括一般内部类(成员内部类)、局部内部类、匿名内部类、静态内部类,他们之间的关系可以如下表示:


一.成员内部类

成员内部类是普通的内部类,它定义在另一个类的内部。成员内部类作为外部类的一个成员存在,与外部类的属性、方法并列

class Student{
	String name;
	int age;
	public Student(String name){
		this.name = name;
	}
	class Learn{
		public void learnMath(){
			System.out.println("Learn Math");
		}
	}
}
这里,Student类称为外部类,Learn类称为成员内部类,它可以直接调用外部类的属性和方法,无论是私有的还是静态的,如下:

class Student{
	private String name = "小明";
	static int age = 15;
	public Student(){
		new Learn().learnMath();    //实例化内部类
	}
	class Learn{
		public void learnMath(){
			System.out.println("Learn Math");
			System.out.println(name);   //获取外部类私有属性
			System.out.println(age);    //获取外部类静态属性
		}
	}
}
public class InnerClassDemo{
	public static void main(String[] args){
		new Student();         //实例化外部类
	}
}

除了用这种方式调用执行,还可以通过如下方式执行:

class Student{
	private String name = "小明";
	static int age = 15;
	class Learn{
		public void learnMath(){
			System.out.println("Learn Math");
			System.out.println(name);
			System.out.println(age);
		}
	}
}
public class InnerClassDemo{
	public static void main(String[] args){
		Student.Learn learn = new Student().new Learn();//可以将Student.Learn当成一个整体
		learn.learnMath();
		/*
		 或者通过这种方式访问
		 Student std = new Student();
		 Student.Learn learn = std.new Learn();
		 learn.learnMath();
		 */
	}
}

运行结果:

Learn Math
小明
15

Student.Learn learn = new Student().new Learn();

1.可以将Student.Learn看成整体,开头的Student是为了标明需要生成的内部类对象在哪个外部类当中

2.必须先有外部类的对象才能生成内部类的对象,因为内部类的作用就是为了访问外部类中的成员变量

注意:当外部类成员变量或方法与内部类成员变量方法同名时,注意调用外部类属性的写法

class Student{
	private String name = "小明";
	private int age = 15;                 //定义外部类变量
	class Learn{
		int age = 14;                 //定义内部类变量
		public void learnMath(){
			int age = 13;         //定义局部变量
			System.out.println(age);
			System.out.println(this.age);
			System.out.println(Student.this.age);
		}
	}
}
public class InnerClassDemo{
	public static void main(String[] args){
		Student.Learn learn = new Student().new Learn();//可以将Student.Learn当成一个整体
		learn.learnMath();
		/*
		 或者通过这种方式访问
		 Student std = new Student();
		 Student.Learn learn = std.new Learn();
		 learn.learnMath();
		 */
	}
}
输出结果:

13
14
15
当没有同名局部变量或者内部变量时,可以用变量名直接访问外部变量,当有同名局部变量或同名内部变量时,直接通过变量名会访问局部变量,this.变量名会访问内部成员变量,要访问外部类变量需要通过 外部类.this.变量名 访问,当然,若此时外部成员变量声明为static,也可以用 外部类.变量名 直接访问外部变量。
二.局部内部类

局部内部类是定义在类的方法中的类。注意:

1.局部内部类就像是方法里面的一个局部变量一样,在局部内部类前不能用修饰符public和private、protected、static等修饰

2.可以访问外部类的局部变量(即方法内的变量),但是变量必须是final的 

3.局部内部类中不可以定义静态变量和方法

局部内部类属于非静态内部类,非静态内部类除了要依靠外部类实例外,还要依赖内部类实例,而静态变量和方法是不需要构建类实例的,所以相矛盾,所以不能定义静态变量和方法

class Student{
	private String name = "小明";
	private int age = 15;  //定义外部类变量
	public void print(final int x){
		class Learn{
			public void learnMath(){
				System.out.println(x);
			}
		}
		new Learn().learnMath();
	}

}
public class InnerClassDemo{
	public static void main(String[] args){
		Student std = new Student();
		std.print(10);
	
	}
}

三.匿名内部类

匿名内部类即没有名字的内部类。表面上看起来它们似乎有名字,实际那不是它们的名字,而是它继承类或接口的名字

这里主要参考http://www.cnblogs.com/nerxious/archive/2013/01/25/2876489.html

注意:

1.正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码编写

2.但使用匿名内部类还有个前提条件:必须继承一个父类或实现一个接口

abstract class Person{
	public abstract void eat();
}
public class InnerDemo{
	public static void main(String[] args){
		Person p = new Person(){
			public void eat(){
				System.out.println("ead something");
			}
		};
		p.eat();
	}
}

匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。

四.静态内部类

静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。可以将静态内部类看成一个外部类,或者看成独立的类,它不能使用外部类的非static成员变量或者方法,下面是其他类访问内部类方法的例子:

程序一:(错误程序)

class Outer{
	private String info = "hello world";     //非静态变量
	static class Inner{
		public void print(){
			System.out.println(info);//内部类获取外部类私有属性
		}
	}
}
public class StaticDemo04{
	public static void main(String[] args){
		new Outer.Inner().print();
	}
}
该程序无法通过,因为静态内部类不能访问外部类非静态成员变量,因为在没有外部类对象的情况下仍然可以创建内部类的对象,而外部类的非static成员必须依附与具体的对象,这点矛盾了
程序二:(正确)

class Outer{
	private static String info = "hello world";
	static class Inner{
		public void print(){
			System.out.println(info);//内部类获取外部类私有属性
		}
	}
}
public class StaticDemo04{
	public static void main(String[] args){
		new Outer.Inner().print();
	}
}
参考链接:

http://www.cnblogs.com/dolphin0520/p/3811445.html

http://www.cnblogs.com/nerxious/archive/2013/01/24/2875649.html
http://www.cnblogs.com/nerxious/archive/2013/01/25/2876489.html

http://blog.csdn.net/zhangjg_blog/article/details/20000769

《Java核心技术 卷一》


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值