Java内部类

1.创建内部类:

将一个类定义在另一个类内部,就是内部类。如果想从外部类的静态方法之外的任意位置创建一个内部类的对象,需要这样指明:OuterClassName.InnerClassName。

实例:outer.java

/**
 * 
 */
package net.pmpa.innerclass;

/**
 * @author liuche
 *
 */
public class Outer {
    private String outername;
    class Inner{
        public Inner(String name){
            System.out.println("new Inner class "+name);
        }
        public String toString(){
            System.out.println("The field outername of the outer class is "+outername);  //直接访问外部类成员outername
            return outername;
        }
    }
    
    public Outer(String outername){
        System.out.println("new Outer class");
        this.outername = outername;   
    }
    
    public Inner getInner(String name){
        return new Inner(name);
    }

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        Outer out = new Outer("SanDiego");
        Outer.Inner in = out.getInner("InnerTest");
        in.toString();
    }

}


2.链接到外部类

内部类对象可以访问创建它的外围对象的所有成员,此外还具有其外围类的所有元素的使用权。当外围类的对象创建了一个内部类的对象时,此内部类对象会获得一个指向外围类对象的引用。内部类的对象只有在与外部类对象相关联时才能被创建。

实例:Sequence.java

/**
 * 
 */
package net.pmpa.innerclass;

/**
 * @author liuche
 *
 */
public class Sequence {
	
	class Dog{
		private String dogname;
		public Dog(String name){
			this.dogname = name;
		}
		public String toString(){
			System.out.println(dogname);
			return dogname;
		}
	}
	
	private Object[] items;
	private int e = 0;
	public Sequence(int size)
	{
		items = new Object[size];
	}
	public void add(Object item){
		if(e<items.length)
		{
			items[e++] = item;
		}
	}
	public Dog getDog(String dogname){
		return new Dog(dogname);
	}
	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Sequence se = new Sequence(3);
		Sequence.Dog d1 = se.getDog("d1");
		Sequence.Dog d2 = se.getDog("d2");
		Sequence.Dog d3 = se.getDog("d3");
		Sequence.Dog d4 = se.getDog("d4");
		se.add(d1);
		se.add(d2);
		se.add(d4);
		se.add(d3);
		
		for(Object i:se.items)
		{
			i.toString();
		}
	}

}

3.使用.this 和.new

(1)需要在内部类中创建外部类的对象时,需要使用外部类.this;
(2)需要在外部类中创建内部类的对象时,需要使用外部类对象.new 内部类;

下边两个类展示了如何使用及原理,House类包含一个内部类Bed,HouseTest类通过main进行测试:

实例:House.java

package net.pmpa.innerclass;

public class House {
	private String housename;
	public House(String name)
	{
		this.housename = name;
	}
	public String getHousename() {
		return housename;
	}
	public void setHousename(String housename) {
		this.housename = housename;
	}
	public class Bed{
		private String bedname = "XiMengSi";
		
		public String getBedname() {
			return bedname;
		}

		public void setBedname(String bedname) {
			this.bedname = bedname;
		}

		public House getHouse(){
			return House.this;    //内部类中创建外部类对象引用
		}
	}

}
实例:HouseTest.java

/**
 * 
 */
package net.pmpa.innerclass;

/**
 * @author liuche
 *
 */
public class HouseTest {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		House h = new House("wanke");
		House.Bed b = h.new Bed();        //通过外部类,创建内部类对象 h.new
		House d = b.getHouse();
		System.out.println(d.getHousename());
	}

}

4.匿名内部类

下面匿名内部类实例,创建了一个继承自E15_AnonymousInnerClass的一个匿名内部类,没有名字的类,因为没有名字所以没有构造方法。通过new表达式返回的引用被自动向上转型为对E15_AnonymousInnerClass的引用。但是通过实例初始化,可以达到为匿名内部类构建一个构造器的效果。

如果在一个方法中创建匿名内部类,并且在匿名内部类的定义体中,应用到了这个变量或者引用。则方法的参数必须定义为final的,例如final String name。

实例:E15_AnonymousInnerClass.java

package net.pmpa.innerclass;

public class E15_AnonymousInnerClass {
	
	private String anonymous;
	public E15_AnonymousInnerClass(String anonymous)
	{
		this.anonymous = anonymous;
	}


}

实例:E15_AnonymousSecondClass.java

package net.pmpa.innerclass;

public class E15_AnonymousSecondClass {
	
	public E15_AnonymousInnerClass getE15_AnonymousInnerClass(final String anonymous){ //anonymous作为匿名内部类的参数,使用了就需要是final类型
		
	return new E15_AnonymousInnerClass(anonymous){       //创建一个继承自E15_AnonymousInnerClass的匿名内部类
		{System.out.println("construct E15_AnonymousInnerClass's root class!" );}  //类似实现匿名内部类的构造方法
			private String function;
			public String getFunction(){
				System.out.println("getFunction()");
				return function;};
		};
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		E15_AnonymousSecondClass s = new E15_AnonymousSecondClass();
		E15_AnonymousInnerClass x = s.getE15_AnonymousInnerClass("test");
	}

}

5.嵌套类

如果不需要内部类对象与其外部类对象之间有联系,那么可以将内部类声明为static,通常称为嵌套类。
(1)要创建嵌套类的对象,并不需要其外围类的对象。
(2)不能从嵌套类的对象中访问非静态的外围类对象。

实例:E18_NestedClass.java

package net.pmpa.innerclass;

public class E18_NestedClass {
	private String outerfield;
	static class Nested{
		public void f(){
			System.out.println("call f() function!");	
			//System.out.println(outerfield);	 //!嵌套类内部不可以访问非静态域(对象)
		}
	}
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		E18_NestedClass.Nested ne = new E18_NestedClass.Nested();
		ne.f();
	}
}


当嵌套类,循环嵌套时,例如A中有B,B中有C,C中有D。生成的class文件,类似于A.class,A$B.class,A$B$C.class,A$B$C$D.class。下例中编译出的class文件分别是:E19_NestedClass.class、E19_NestedClass$E19_Nested1.class、E19_NestedClass$E19_Nested1$E19_Nested2.class、E19_NestedClass$E19_Nested1$E19_Nested2$E19_Nested3.class、E19_NestedClass$E19_Nested1$E19_Nested2$E19_Nested3$E19_Nested4.class

实例:E19_NestedClass.java

package net.pmpa.innerclass;

public class E19_NestedClass {
	private String nestedstring;
	static class E19_Nested1
	{
		public void f(){
			System.out.println("Nested1 call f() function!");	
		}	
		static class E19_Nested2
		{
			public void f(){
				System.out.println("Nested2 call f() function!");	
			}	
			static class E19_Nested3
			{
				public void f(){
					System.out.println("Nested3 call f() function!");	
				}
				static class E19_Nested4
				{
					public void f(){
						System.out.println("Nested4 call f() function!");	
					}	
				}
			}
		}
	}
}

5.接口内部的类

正常情况下,不能在接口内部放置任何代码,但是嵌套类可以作为接口的一部分。甚至可以在内部类中实现外围接口。

实例:E21_ClassInInterface.java

package net.pmpa.innerclass;

public class E21_ClassInInterface {
	
	
	interface Inter21{
		void f();
		
		static class Test{     //接口内部定义的内部类。
			static void call(Inter21 i)
			{
				System.out.println("Calling f()");
				i.f();
			}
		}
		
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		Inter21 i = new Inter21(){
			public void f()
			{
				System.out.println("prinf f()!!!");
			}
			
		};
		Inter21.Test.call(i);
	}

}








 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值