内部类

所谓内部类就是定义在一个类内部的类,内部类的概念是在JDK1.1中被引用的,引入内部类主要有以下一些考虑:

*内部类对象能访问它所处类的私有数据

*内部类能够隐藏起来不为同一个包中的其他类访问

*匿名内部类可以方便地用在回调方法中,典型应用是java(android)图形编程中的事件处理

1.成员内部类,顾名思义,是一个可以看成是外部类的非静态成员的内部类,成员内部类和普通的成员没什么区别,可以与普通成员一样修饰和限制。它具有以下特点:

*成员内部类可以访问外部类的私有成员或属性

*外部类不能访问成员内部类中的私有属性

*成员内部类是一个编译时的概念,一旦编译成功,就会成为与外部类完全不同的类

*内部类和外部类在编译时是两个不同的类,内部类对外部类没有任何依赖

内部类和外部类可以相互访问,首先在外部类的内部可以创建内部类的对象并直接使用:

Inner i = new Inner();

在外部类的外部需要先建立一个外部类对象,然后再生成一个内部类对象,这是因为内部类相当于外部类的成员,而成员只有在所属对象存在的情况下才存在:

Outer.Inter inn =new Outer().new Inter();  Outer.Inter inn = out.newInter();

*内部类可以访问外部类的任何成员

*外部类需要创建内部类的对象才可以访问内部类的成员

package yy;
public class OuterA {
private String name = "maidou";
	private static String address = "Harbin";
	public void m1(){
		System.out.println("OuterA的方法m1!");
	}
	public class InnerA{
		public InnerA(){
		}
		String name = "guai";
		public void m2(){
			System.out.println("OuterA的name:"+OuterA.this.name);
			System.out.println("OuterA的address:"+address);
			System.out.println("OuterA的内部类InnerA的name:"+this.name);
		}
	}
	
	public static void main(String[] args) {
		OuterA out = new OuterA();
		out.m1();
		OuterA.InnerA in = new OuterA().new InnerA();
		in.m2();
		
	}
}
运行结果:
OuterA的方法m1!
OuterA的name:maidou
OuterA的address:Harbin

    

        2.在方法中定义的内部类成为局部内部类,它是一个只有在局部有效的内部类,局部内部类作用域与变量相同,只在其所在的语句块中有效,所以只能在其有效的位置访问或创建。

*局部内部类的语法规则和成员内部类的语法规则相同,只是局部内部类是被定义在方法中

*与局部变量类似,在局部内部类前不加修饰符publicprivate,其范围为定义它的代码块

*局部内部类可以访问外部类的私有实例变量和局部final常量

*在外部类的外部不能直接访问局部内部类,这样就有效的保证了局部内部类对外部是不可见的,但是如果在类外不能访问局部内部类,那么局部内部类的意义就要大打折扣了。解决方法是通过局部内部类和接口达到一个强制的弱耦合关系,用局部内部类来实现接口,并在方法中返回接口类型,这样既可以使局部类不可见,屏蔽实现类的可见性,又可以在类的外部访问内部类的方法

package yy;
public class OuterBTest {
	public static void main(String[] args) {
		OuterB outb = new OuterB();
		MyInter obj = outb.m1();
		obj.m3();
		obj.m4();
	}
}
	class OuterB{
		private int a = 10;
		public MyInter m1(){
			int b =20;
			final int c = 30;
			
			class InnerB implements MyInter{
				public void m3(){
					//System.out.println("局部内部类InnerB的m3方法调用局部变量b="+b);不能访问局部非final变量
					System.out.println("可访问外部类的私有变量a"+a);
					
				}
				public void m4(){
					System.out.println("可访问外部类的局部final变量:"+c);
				}
			}
			return new InnerB();
		}
	}

interface MyInter{
	public void m3();
	public void m4();
}

结果:
可访问外部类的私有变量a10
可访问外部类的局部final变量:30

    

3.静态内部类其实已经脱离了外部类,在创建静态内部类对象时也不需要外部类对象的存在,其实质是一个放置在别的类内部的普通类,而关键字static也只是说明其在创建对象时不依赖外部类对象的存在,并不是说这个类本身是静态的。

*静态内部类与前面讲的两种非静态内部类的语法基本相同,区别主要在内部类的声明前要加上static关键字,另外,静态内部类也不可以用private进行定义

*与成员内部类和局部内部类恰巧相反,静态内部类只能访问外部类的静态成员,不能访问外部类的非静态成员

*静态内部类的对象可以直接生成,而不需要外部类的对象来生成,这样实际使静态内部类成为了一个顶级类,这主要是因为静态内部类是外部类的静态成员,并不依赖于外部类的对象而存在

*静态内部类与非静态内部类的区别是本质上的。

 

package yy;

public class OutC {
	private String name = "maidou";
	private static String address = "Harbin";
	public static void m1(){
		System.out.println("外部类的方法-address:"+address);
	}
	public static class InnerC{
		public void m2(){
			//System.out.println("name"+name);只能调用外部类的static属性
			System.out.println("静态内部类InnerC调用OutC的address:"+address);
			m1();
		}
	}
	public static void main(String[] args) {
		OutC.InnerC in = new OutC.InnerC();
		in.m2();
	}
	
}
输出:
静态内部类InnerC调用OutC的address:Harbin
外部类的方法-address:Harbin

    

4.匿名内部类是一种特殊的局部内部类,这种内部类没有类名,该类适用于只使用一次而且不需要多次创建的对象的类,使用匿名内部类可以使类代码与创建对象同事完成,这样做不但方便,而且还提高了代码的可维护性。

*没有类名,没有class关键字,没有构造方法,有继承但没有extends关键字,有类体

*大部分匿名内部类用于接口回调

*匿名内部类在编译的时候有系统自动起名

*匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写
package yy;

public class OutD {

	public static void main(String[] args) {
		AbstractFather af = new AbstractFather() {
			{
				count = (int) (100*Math.random());
			}//定义语句块
			@Override
			//实现父类的方法
			public void m() {
				System.out.println("您的号码是:"+count);
			}
		};
		af.m();
	}
}
abstract class AbstractFather{
	int count;
	abstract void m();
}
输出:
您的号码是:27

好了,可以继续昨天的任务啦