Sunday, February 18, 2018

Java Nested class - inner class


https://docs.oracle.com/javase/tutorial/java/javaOO/nested.html


class OuterClass {
    ...
    class NestedClass {
        ...
    }
}



Nested classes are divided into two categories: static and non-static. Nested classes that are declared static are called static nested classes. Non-static nested classes are called inner classes.


class OuterClass {
    ...
    static class StaticNestedClass {
        ...
    }
    class InnerClass {
        ...
    }
}


A nested class is a member of its enclosing class. 

Non-static nested classes (inner classes) have access to other members of the enclosing class, even if they are declared private. 

Static nested classes do not have access to other members of the enclosing class. As a member of the OuterClass, a nested class can be declared privatepublicprotected, or package private. (Recall that outer classes can only be declared public or package private.)


class A1 {
    public int val = 10;
    public static int staticVal = 99;

    // Note if this is not static class    // we have to initialze an A1 objec say a1;    // then use A1.B1 b = a1.new B1()    // to create a new object    // Not this class is not static class, so    // it can not have static variable    // Note B1 is associated with outerClass objects    // So it can only be innitialized when there is    // a outer class object    // eg A1 a1 = new A1();    //    A1.B1 = a1.new B1();    class B1 {
        public int bval = val;
        public int b2val = staticVal;

        // The following has compiler issue, won't compile        // public static int bStaticVal = staticVal;    }


    // static inner class    // it can only use static variable from outer class    // because when outer Class static variable get initialized    // is earlier than other variables.    // This means inner static class can only use initialized outer    // class static variable. It can NOT use outer class object variables.    // But inner static class can be used as any other top class.    // which means it does not belong to any outer class object.    // It can be initialized as follows:    // eg A1.C1 c1 = new A1.C1();    //    static class C1 {
        public int cval = staticVal;
        public int a = 50;
        public int b = 500;

        // Note: the following has compiling issues        // since it is a static class, it can only use static variable        // public int c2val = val;    }


    int t() {
        return 1;
    }

    // Anonymous class    static A1 a =  new A1() {
        int t() { return 2; }
    };
}

public class NestedClassTest {
    public static void main(String[] args) {

        System.out.println(A1.a.t());
        A1 a1 = new A1();
        System.out.println(a1.t());

        A1.B1 b1 = a1.new B1();
        System.out.println(b1.bval + ", " + b1.b2val);


        A1.C1 c1 = new A1.C1();
        System.out.println(c1.cval + ", " + c1.a + ", " + c1.b);

        return;
    }
}


Inner Classes

As with instance methods and variables, an inner class is associated with an instance of its enclosing class and has direct access to that object's methods and fields. Also, because an inner class is associated with an instance, it cannot define any static members itself.
Objects that are instances of an inner class exist within an instance of the outer class. Consider the following classes:
class OuterClass {
    ...
    class InnerClass {
        ...
    }
}

An instance of InnerClass can exist only within an instance of OuterClass and has direct access to the methods and fields of its enclosing instance.
To instantiate an inner class, you must first instantiate the outer class. Then, create the inner object within the outer object with this syntax:
OuterClass.InnerClass innerObject = outerObject.new InnerClass();


Note: Non-static class is associated with class object, can access outer class object variables.
Note: Static class is associated with class, can only access outer class static variable.

Shadowing

 
public class ShadowTest {

    public int x = 0;

    class FirstLevel {

        public int x = 1;

        void methodInFirstLevel(int x) {
            System.out.println("x = " + x);
            System.out.println("this.x = " + this.x);
            System.out.println("ShadowTest.this.x = " + ShadowTest.this.x);
        }
    }

    public static void main(String... args) {
        ShadowTest st = new ShadowTest();
        ShadowTest.FirstLevel fl = st.new FirstLevel();
        fl.methodInFirstLevel(23);
    }
}
The following is the output of this example:
x = 23
this.x = 1
ShadowTest.this.x = 0


Use Inner class as helper class. Eg(Collection Data structure with inner iterator helper)

You can use inner classes to implement helper classes such as the one shown in the this example. To handle user interface events, you must know how to use inner classes, because the event-handling mechanism makes extensive use of them.

public class DataStructure {
    
    // Create an array
    private final static int SIZE = 15;
    private int[] arrayOfInts = new int[SIZE];
    
    public DataStructure() {
        // fill the array with ascending integer values
        for (int i = 0; i < SIZE; i++) {
            arrayOfInts[i] = i;
        }
    }
    
    public void printEven() {
        
        // Print out values of even indices of the array
        DataStructureIterator iterator = this.new EvenIterator();
        while (iterator.hasNext()) {
            System.out.print(iterator.next() + " ");
        }
        System.out.println();
    }
    
    interface DataStructureIterator extends java.util.Iterator<Integer> { } 

    // Inner class implements the DataStructureIterator interface,
    // which extends the Iterator<Integer> interface
    
    private class EvenIterator implements DataStructureIterator {
        
        // Start stepping through the array from the beginning
        private int nextIndex = 0;
        
        public boolean hasNext() {
            
            // Check if the current element is the last in the array
            return (nextIndex <= SIZE - 1);
        }        
        
        public Integer next() {
            
            // Record a value of an even index of the array
            Integer retValue = Integer.valueOf(arrayOfInts[nextIndex]);
            
            // Get the next even element
            nextIndex += 2;
            return retValue;
        }
    }
    
    public static void main(String s[]) {
        
        // Fill the array with integer values and print out only
        // values of even indices
        DataStructure ds = new DataStructure();
        ds.printEven();
    }
}
The output is:
0 2 4 6 8 10 12 14 
Note that the EvenIterator class refers directly to the arrayOfInts instance variable of the DataStructure object.





























No comments:

Post a Comment

java special for collection size, array size, and string size

Size: For Collections (eg: Map, List, etc ): usually it use collection.size(), eg         Map<Character, Integer> map ...