您的位置:首页 > 编程语言 > Java开发

java中内部类的使用

2015-09-30 00:34 459 查看
内部类是定义在另一个类中的类,内部类的作用如下:

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核心技术 卷一》

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java 内部类