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

Java内部类

2015-10-20 20:15 423 查看

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);
}

}



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