什么是 Java 中的内部类:
1.顾名思义,内部类( Inner Class )就是定义在另外一个类里面的类。与之对应,包含内部类的类被称为外部类。
为什么要用内部类?
内部类的主要作用如下:
1. 内部类提供了更好的封装,可以把内部类隐藏在外部类之内,不允许同一个包中的其他类访问该类
2. 因为内部类可以随意使用外部类的成员变量(包括私有)而不用生成外部类的对象。
3. 内部类所实现的功能使用外部类同样可以实现,只是有时使用内部类更方便
内部类分类:
- 成员内部类
- 静态内部类
- 方法内部类
- 匿名内部类
下面写一些简单的代码帮助大家理解所有的内部类:
先来看看内部类的基本结构:
1 public class Out{ 2 class Inner { 3 public void show(){ 4 System.out.println("内部类的方法:"); 5 } 6 } 7 public static void main(Sring [] args){ 8 Out.Inner in = new Out().new Inner();//创建内部类的方法 9 /* 10 Out out = new Out(); 11 Out.Inner in = out.new Inner(); 12 */ 13 in.show(); 14 } 15 }
Out.Inner in = new Out().new Inner()可以用来生成内部类的对象,这种方法存在两个小知识点需要注意
1.开头的Out是为了标明需要生成的内部类对象在哪个外部类当中
2.必须先有外部类的对象才能生成内部类的对象,因为内部类的作用就是为了访问外部类中的成员变量
1.成员内部类----也称为普通内部类它是最常见的内部类
1 //外部类Out 2 public class Out{ 3 4 //外部类的私有属性name 5 private String name = "我爱Java"; 6 //外部类的成员属性 7 int age = 20; 8 //成员内部类Inner 9 public class Inner { 10 String name = "没房没车"; 11 //内部类中的方法 12 public void show() { 13 System.out.println("外部类中的name:" + Out.this.name); 14 System.out.println("内部类中的name:" +name); 15 System.out.println("外部类中的age:" + age); 16 } 17 } 18 19 //测试成员内部类 20 public static void main(String[] args) { 21 22 //创建外部类的对象 23 Out o = new Out(); 24 25 //创建内部类的对象 26 Inner inn = o.new Inner(); 27 28 //调用内部类对象的show方法 29 inn.show(); 30 } 31 }
不过要注意的是,当成员内部类拥有和外部类同名的成员变量或者方法时,会发生隐藏现象,即默认情况下访问的是成员内部类的成员。如果要访问外部类的同名成员,需要以下面的形式进行访问:
Out.this.name
外部类.this.成员变量;
外部类.this.成员方法;
需要注意:虽然成员内部类可以无条件地访问外部类的成员,而外部类想访问成员内部类的成员却不是这么随心所欲了。在外部类中如果要访问成员内部类的成员,必须先创建一个成员内部类的对象,再通过指向这个对象的引用来访问:
2..静态内部类
静态内部类也是定义在另一个类里面的类,只不过在类的前面多了一个关键字static。静态内部类是不需要依赖于外部类的,这点和类的静态成员属性有点类似,并且它不能使用外部类的非static成员变量或者方法,这点很好理解,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象。
1 //外部类 2 public class Out{ 3 // 外部类中的静态变量score 4 private static int score = 84; 5 // 创建静态内部类 6 public static class SInner { 7 // 内部类中的变量score 8 int score = 91; 9 public void show() { 10 System.out.println("访问外部类中的score:" + Out.score); 11 System.out.println("访问内部类中的score:" + score); 12 } 13 } 14 15 // 测试静态内部类 16 public static void main(String[] args) { 17 // 直接创建内部类的对象 18 SInner si = new SInner() 19 // 调用show方法 20 si.show(); 21 } 22 }
3.方法内部类--也称为局部内部类
方法内部类就是内部类定义在外部类的方法中,方法内部类只在该方法的内部可见,即只在该方法内可以使用。
1 //外部类 2 public class MOut{ 3 private String name = "我爱Java"; 4 5 // 外部类中的show方法 6 public void show() { 7 // 定义方法内部类 8 class MInner { 9 int score = 83; 10 public int getScore() { 11 return score + 10; 12 } 13 } 14 15 // 创建方法内部类的对象 16 MInner mi = new MInner(); 17 // 调用内部类的方法 18 int newScore = mi.getScore(); 19 System.out.println("姓名:" + name + " 加分后的成绩:" + newScore); 20 } 21 22 // 测试方法内部类 23 public static void main(String[] args) { 24 25 // 创建外部类的对象 26 MOut mo = new Mout(); 27 // 调用外部类的方法 28 mo.show(); 29 } 30 }
注意,局部内部类就像是方法里面的一个局部变量一样,是不能有public、protected、private以及static修饰符的。
4.匿名内部类(这部分转载地址:http://www.cnblogs.com/dolphin0520/p/3811445.html)
匿名内部类应该是平时我们编写代码时用得最多的,在编写事件监听的代码时使用匿名内部类不但方便,而且使代码更加容易维护。下面这段代码是一段Android事件监听代码:
1 scan_bt.setOnClickListener(new OnClickListener() { 2 3 @Override 4 public void onClick(View v) { 5 // TODO Auto-generated method stub 6 7 } 8 }); 9 10 history_bt.setOnClickListener(new OnClickListener() { 11 12 @Override 13 public void onClick(View v) { 14 // TODO Auto-generated method stub 15 16 } 17 });
这段代码为两个按钮设置监听器,这里面就使用了匿名内部类。这段代码中的:
new OnClickListener() { @Override public void onClick(View v) { // TODO Auto-generated method stub } }
就是匿名内部类的使用。代码中需要给按钮设置监听器对象,使用匿名内部类能够在实现父类或者接口中的方法情况下同时产生一个相应的对象,但是前提是这个父类或者接口必须先存在才能这样使用。
需要注意:
1.匿名内部类也是不能有访问修饰符和static修饰符的。
2.匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。匿名内部类在编译的时候由系统自动起名为Outter$1.class。一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。