Thinking in java Chapter10 内部类

内部类:一个类的定义放在另一个类的定义内部

  • 逻辑相关的类组织在一起,并控制位于内部的类的可视性。
  • 与组合是完全不同的概念。

    10.1 创建内部类

// 创建内部类
public class Parcel1 {
    class Contents{
        private int i = 11;
        public int value(){ return i;}
    }
    class Destination{
        private String label;
        Destination(String whereTo){ label = whereTo;}
        String readLable(){ return label;}
    }
    // Using inner classes looks just like using any other class. within Parcel1:
    public void ship(String dest){ // 使用内部类
        Contents c = new Contents();
        Destination d = new Destination(dest);
        System.out.println(d.readLable());
    }

    public static void main(String[] args) {
        Parcel1 p = new Parcel1();
        p.ship("Tasmania");
    }
}
// 返回一个指向内部类的引用
public class Parcel2 {
    class Contents{
        private int i = 11;
        public int value(){ return i;}
    }
    class Destination{
        private String label;
        Destination(String whereTo){ label= whereTo;}
        String readLabel(){return label;}
    }
    public Destination to(String s){
        return new Destination(s);
    }
    public Contents contents(){
        return new Contents();
    }
    public void ship(String dest){
        Contents c = contents();
        Destination d = to(dest);
        System.out.println(d.readLabel());
    }

    public static void main(String[] args) {
        Parcel2 p = new Parcel2();
        p.ship("Tasmania");
        Parcel2 q= new Parcel2();
        Parcel2.Contents c = q.contents(); // 创建内部类对象 outerClassName.InnerClassName
        Parcel2.Destination d = q.to("Borneo");

    }
}

10.2 创建到外部类

内部类对象拥有一个对外围类对象的引用

package chapter10Innerclasses;
//

interface Selector{ // 迭代器模式
    boolean end();
    Object current();
    void next();
}

public class Sequence {
    private Object[] items;
    private int next = 0;
    public Sequence(int size) {items = new Object[size];}
    public void add(Object x){
        if(next < items.length)
            items[next++] = x;
    }
    private class SequenceSelector implements Selector {
        private int i = 0;

        @Override
        public boolean end() {
            return i == items.length;
        }

        @Override
        public Object current() {
            return items[i];
        }

        @Override
        public void next() {
            if (i < items.length) i++;

        }
    }

    public Selector selector(){
        return new SequenceSelector();
    }

    public static void main(String[] args) {
        Sequence sequence = new Sequence(10);
        for (int i = 0;i < 10;i++)
            sequence.add(Integer.toString(i));
        Selector selector = sequence.selector();
        while (!selector.end()){
            System.out.println(selector.current() + " ");
            selector.next();
    }
    }
}

10.3 使用.this与.new

package chapter10Innerclasses;

public class DotThis {
    void f(){
        System.out.println("DotThis.f()");
    }
    public class Inner{
        public DotThis outer(){
            return DotThis.this; // 外部类.this  外围类引用
        }
    }
    public Inner inner(){
        return new Inner();
    }

    public static void main(String[] args) {
        DotThis dt = new DotThis();
        DotThis.Inner dti = dt.inner();
        dti.outer().f();
    }
}/* Output
DotThis.f()
*/
public class DotNew {
    public class Inner{}

    public static void main(String[] args) {
        DotNew dn = new DotNew();
        DotNew.Inner dni = dn.new Inner(); // 创建某个内部类的对象  不能用外部类名称如DotNew,而是用外部类的对象创建
    }
}
package chapter10Innerclasses;

public class Parcel3 {
    class Contents{
        private int i =11;
        public int value(){
            return i;
        }
    }
    class Destination{
        private String label;
        Destination(String whereTo){label = whereTo;}
        String readLabel(){return label;}
    }

    public static void main(String[] args) {
        Parcel3 p = new Parcel3();
        Parcel3.Contents c = p.new Contents();
        Parcel3.Destination d = p.new Destination("Tasmania"); // 内部类对象会 暗暗的连接到创建它到外部类对象上。
        // 如果创建到是嵌套类(静态内部类),就不需要对外部类对象对引用。这句话没有例子
    }
}

10.4 内部类与向上转型

package chapter10Innerclasses;

class Parcle4{
    private class PContents implements Contents{
        private int i = 11;
        public int value(){return i;}
    }

    protected class PDestination implements Destination{
        private String label;
        private PDestination(String whereTO){
            label = whereTO;
        }
        @Override
        public String readlabel() {
            return label;
        }
    }
    public Destination destination(String s){
        return new PDestination(s);
    }
    public Contents contents(){
        return new PContents();
    }
}
public class TestParcel {
    public static void main(String[] args) {
        Parcle4 p = new Parcle4();
        Contents c = p.contents();  // 向上转型
        Destination d = p.destination("Tasmania");
//        Parcle4.PContents pc = p.new PContents(); // 不能访问私有类 不能向下转型
    }
}
package chapter10Innerclasses.e6.package1;

public interface Interface01 {
    void f();
}

package chapter10Innerclasses.e6.package2;

import chapter10Innerclasses.e6.package1.Interface01;

public class Class2 {
    protected class Inner implements Interface01{

        @Override
        public void f() {
            System.out.println("class2.inner.method()");
        }

        public Inner(){}  // Inner 为 protected,强制 构造函数为public
    }
}

package chapter10Innerclasses.e6.package3;

import chapter10Innerclasses.e6.package1.Interface01;
import chapter10Innerclasses.e6.package2.Class2;

public class Class3 extends Class2 {
    public Interface01 get(){
        return new Inner();  // 构造函数为public 才能new
    }

    public static void main(String[] args) {
        new Class3().get().f();

    }

}
package chapter10Innerclasses.e7;

public class ClassA {
    private int i = 10;
    private void methodA(){
        System.out.println("ClassA private methodA(),and i = " + i);
    }
    class Inner{
        void methodB(){
            i++;
            methodA(); // 内部类可以访问 外围类的私有字段和私有方法
            System.out.println("ClassA Inner methodB(),and i = " + i);

        }
    }

    public void methodC(){
        Inner inner =  new Inner();
        inner.methodB();
        System.out.println("methodC and i = " + i);
    }

    public static void main(String[] args) {
        ClassA classA = new ClassA();
        classA.methodC();
    }
}

10.5 在方法和作用域内的内部类

内部类作用

  • 实现某类型的接口,可以创建并返回对其对引用
  • 解决复杂问题,创建一个类辅助解决,不希望它公共可用
  1. 局部内部类:方法中的类

package chapter10Innerclasses;

public class Parcel5 {
    public Destination destination(String s){
        class PDestination implements Destination{ // 方法中的类
            private String label;
            private PDestination(String whereTo){
                label = whereTo;
            }

            @Override
            public String readLabel() {
                return label;
            }
        }
        return new PDestination(s); // 返回的是 Destination 的引用
    }


    public static void main(String[] args) {
        Parcel5 p = new Parcel5();
        Destination d = p.destination("Tasmania"); // Destination 向上转型
        System.out.println(d.readLabel());
    }
}
  1. 作用域中嵌入内部类

package chapter10Innerclasses;
// 作用域内嵌入一个内部类
public class Parcel6 {
    private void interalTracking(boolean b){
        if (b){
            class TrackingSlip{ // 跟踪单  嵌入在if作用域中,并不是说该类创建是有条件的。它其实是与别的类一起编译的。 超出作用域外,不可用。除此之外,与普通类一样。
                private String id;
                TrackingSlip(String s){
                    id = s;
                }
                String getSlip(){
                    return id;
                }
            }
            TrackingSlip ts = new TrackingSlip("slip");
            String s = ts.getSlip();
        }
//        TrackingSlip ts = new TrackingSlip("slip"); // 不能用在这里,超出作用域
    }

    public void track(){interalTracking(true);}

    public static void main(String[] args) {
        Parcel6 p = new Parcel6();
        p.track();
    }
}

10.6 匿名内部类

  1. 实现了接口的匿名类

package chapter10Innerclasses;

public class Parcel7 {
    public Contents contents(){
        return new Contents() { // 使用默认构造器生成Contents
            private int i = 11;

            @Override
            public int value() {
                return i;
            }
        }; //需要分号
    }

    public static void main(String[] args) {
        Parcel7 p = new Parcel7();
        Contents c = p.contents();
        
    }
}
  1. 扩展了有非默认构造器的类

package chapter10Innerclasses;

class Wrapping {
    private int i ;
    Wrapping(int x) {
        i = x;
        System.out.println("Wrapping constructor x = " + x);
    }
    public int value(){return i;}

}

public class Parcel8 {
    public Wrapping wrapping(int x) { 
        return new Wrapping(x) { // 传参数给构造器
            public int value() {
                return super.value() * 47;
            }
        }; // 分号
    }

    public static void main(String[] args) {
        Parcel8 p = new Parcel8();
        Wrapping w = p.wrapping(10);
        System.out.println(w.value());

    }
}
  1. 执行字段初始化

  2. 通过实例初始化实现构造(匿名类不可能有构造器)

猜你喜欢

转载自www.cnblogs.com/erinchen/p/11830479.html