/*
  Copyright (c) October 2013 by Paweł Rzechonek
  W programie zdefiniowano klasę zewnętrzną Z
  ze składową instancyjną klasą wewnętrzną W
  oraz składową statyczną klasą wewnętrzną SW.
  Istotne elementy w programie:
    * odwołania do składowych w klasie zewnętrznej z obiektów klas wewnętrznych;
    * przysłanianie nazw pól.
*/

class Z {

    private int p = 0, q = 1;
    class W {
        private int p = 2, s = 3;
        public void licz () {
            Z.this.p++; // pole p w klasie zewnętrznej jest przesłonięte
            q += p;
            p++;
            s++;
        }
        public String toString () {
            return "Z.this.p = "+Z.this.p+" / Z.this.q = "+Z.this.q+" / [W]p = "+p+" / [W]s = "+s;
        }
    }

    private static int r = 2;
    static class SW {
        private int q = 5, r = 7;
        public void licz () {
            Z.r *= 2; // pole statyczne r w klasie zewnętrznej jest przesłonięte
            q += r;
            r *= 2;
        }
        public String toString () {
            return "Z.r = "+Z.r+" / [SW]q = "+q+" / [SW]r = "+r;
        }
    }
}

public class WewZew {

    public static void main(String[] args) {
    	Z z = new Z();
    	Z.W w = z.new W(); // obiekt klasy wewnętrznej musi być powiązany z jakimś obiektem klasy zewnętrznej
        System.out.println(w);
        w.licz();
        System.out.println(w);
        w.licz();
        System.out.println(w);

        Z.SW sw = new Z.SW(); // obiekt statycznej klasy wewnętrznej nie jest powiązany z żadnym obiektem klasy zwenętrznej
        System.out.println(sw);
        sw.licz();
        System.out.println(sw);
        sw.licz();
        System.out.println(sw);
    }
}
