第十章 内部类1

说明:内部类和组合是完全不同的概念,内部类看起来更像是一种代码隐藏机制。内部类了解外围类,并能与之通信。要创建一个内部类是非常简单的,只要将一个类定义在另一个类的内部即可。

创建内部类对象的方式:

1.如果内部类为公有、静态内部类:

package think.in.java.test;

/**
 * 一个包裹着公有的、静态的、内部类的外部类
 * @author Administrator
 *
 */
public class Outer {
    private String oStr;
    
    Outer(String oStr){
        this.oStr = oStr;
    }
    
    public Inner getInner(String str) {
        return new Inner(str);
    }
    
    public static class Inner{
        private String inStr;
        
        Inner(String inStr){
            this.inStr = inStr;
        }
        
        public void print() {
            System.out.println(this.inStr);
        }
    }
}

测试程序:

package think.in.java.test;

import think.in.java.test.Outer.Inner;

/**
 * 创建公有的、静态的、内部类对象的方式
 * @author Administrator
 *
 */
public class Tset {

    public static void main(String[] args) {

        //创建方式1
        Outer o = new Outer("I am outer");
        Inner in1 = o.getInner("I am Inner1");
        in1.print();
        
        //创建方式2 -- 推荐
        Inner in2 = new Inner("I am Inner2");
        in2.print();
        
        //创建方式3
        Outer.Inner in3 = new Outer.Inner("I am Inner3");
        in3.print();
        
        //创建方式4
        Outer.Inner in4 = new Inner("I am Inner4");
        in4.print();
        
        //Illegal enclosing instance specification for type Outer.Inner
        //Outer.Inner in5 = o.new Inner("I am Inner5");
    }

}

输出:

I am Inner1
I am Inner2
I am Inner3
I am Inner4

总结:静态内部类不能使用非静态内部类的创建方式,即上测试类中in5对象的创建方式

2.如果内部类为公有、非静态内部类:

package think.in.java.test;

/**
 * 一个包裹着公有的、非静态的、内部类的外部类
 * @author Administrator
 *
 */
public class Outer {
    private String oStr;
    
    Outer(String oStr){
        this.oStr = oStr;
    }
    
    public Inner getInner(String str) {
        //return new Outer.Inner(str);
        return new Inner(str);
    }
    
    public class Inner{
        private String inStr;
        
        Inner(String inStr){
            this.inStr = inStr;
        }
        
        public void print() {
            System.out.println(this.inStr);
        }
    }
}

测试程序:

package think.in.java.test;

import think.in.java.test.Outer.Inner;

/**
 * 创建公有的、非静态的、内部类对象的方式
 * @author Administrator
 *
 */
public class Tset {

    public static void main(String[] args) {

        //创建方式1
        Outer o = new Outer("I am outer");
        Outer.Inner in1 = o.getInner("I am Inner1");
        //Inner in1 = o.getInner("I am Inner1");
        in1.print();
        
        //创建方式2
        Inner in2 = o.new Inner("I am Inner2");
        //Outer.Inner in2 = o.new Inner("I am Inner2");
        in2.print();
        
        //error,不能引用外部类的名字去创建这个对象,你应该使用外部类的对象去创建内部类,像in2那样
        //Inner in3 = o.new Outer.Inner("I am Inner2");
        
        //error!
        //Inner in3 = new Outer.Inner("I am Inner3");
        //Inner in4 = new Inner("I am Inner3");
        //Inner in5 = new Inner("I am Inner5");
    }

}

输出:

I am Inner1
I am Inner2

总结:创建非静态内部类不能使用像静态内部类那样直接创建!但创建静态或非静态类都可以像创建方式1中那样,在外部类的某个方法里直接创建,在由外部类通知这个方法,获取内部类对象。

学习:针对非静态类,在拥有外部类对象之前是不可能创建内部类对象的,这是因为内部类对暗暗地连接到创建它的外部类对象上,这也是为什么非静态内部类具有外部类所有成员访问权的原因,当某个外围类对象创建了一个内部类对象时,此内部类对象必定会秘密捕获一个指向那个外围类对象的引用。然后,在你访问外围类的成员时,就是用那个引用来选择外围类的成员。

对于静态的内部类不具有访问外部类所有成员方法和非静态变量的权利

package think.in.java.test;

/**
 * 一个包裹着公有的、非静态的、内部类的外部类
 * @author Administrator
 *
 */
public class Outer {
    private String oStr;
    
    Outer(String oStr){
        this.oStr = oStr;
    }
    
    public Inner getInner(String str) {
        return new Inner(str);
    }
    
    public static void oPrint(String str) {
        System.out.println(str);
    }
    
    public static class Inner{
        private String inStr;
        
        Inner(String inStr){
            this.inStr = inStr;
        }
        
    }
    
    public static void main(String[] args) {
        Outer o = new Outer("i am outer");
        Inner in = new Inner("I am Inner");
        
        System.out.println(o.oStr);
        //不具有访问外围类属性的权利
        //System.out.println(in.oStr);
        
        o.getInner("hello");
        //不具有访问外围类方法的权利
        //in.getInner("hello");
        
        //可以调用外部类静态方法
        oPrint("hello");
        
    }
}

猜你喜欢

转载自www.cnblogs.com/liudaihuablogs/p/9147333.html