Search code examples
javaoverloadinglocalinner-classesanonymous-inner-class

overloaded constructor InnerClass inside a method


I'm reading the book "Thinking in Java" by Bruce Eckel. I came across this assertion in the inner class chapter, which says: "the only justification for using a local inner class instead of an anonymous inner class is if you need a named constructor and/or an overloaded constructor"

I don't now if i understood well but: Is this the way of overloading constructors of Inner(local classes) inside method?

abstract class ForInner {
abstract String getName();
abstract void setName(String newName);
abstract int getNumber();
abstract void setNumber(int newNumber);

} class Outer{

public ForInner getSomeInner(String name) {
    class LocalInner extends ForInner{
        private String myName;
        private int myNumber;
        public LocalInner(String myName) {
            this.myName = myName;
        }
        public String getName() {
            return myName;
        }
        public void setName(String newName) {
            myName = newName;
        }
        public int getNumber() {
            return myNumber;
        }
        public void setNumber(int newNumber) {
            myNumber = newNumber;
        }
    }
    return new LocalInner(name);
}
public ForInner getSomeInner(int number) {
    class LocalInner extends ForInner{
        private String myName;
        private int myNumber;
        public LocalInner(int myNumber) {
            this.myNumber = myNumber;
        }
        public String getName() {
            return myName;
        }
        public void setName(String newName) {
            myName = newName;
        }
        public int getNumber() {
            return myNumber;
        }
        public void setNumber(int newNumber) {
            myNumber = newNumber;
        }
    }
    return new LocalInner(number);
}

}

I'm not sure if the assertion referring to this. But might have a guess that is not the case because How different it would be of using in this way

abstract class ForInner {
abstract String getName();
abstract void setName(String newName);
abstract int getNumber();
abstract void setNumber(int newNumber);

}

lass Outer{
public ForInner inner (String name) {
    return new ForInner() {
        private String myName;
        private int myNumber;
        {
            myName = name;
        }
        public String getName() {
            return myName;
        }
        public void setName(String newName) {
            myName = newName;
        }
        public int getNumber() {
            return myNumber;
        }
        public void setNumber(int newNumber) {
            myNumber = newNumber;
        }
    };
}
public ForInner inner (int number) {
    return new ForInner() {
        private String myName;
        private int myNumber;
        {
            myNumber = number;
        }
        public String getName() {
            return myName;
        }
        public void setName(String newName) {
            myName = newName;
        }
        public int getNumber() {
            return myNumber;
        }
        public void setNumber(int newNumber) {
            myNumber = newNumber;
        }
    };
}

} thank in advance?


Solution

  • public class OuterClass {
        Runnable printA = new Runnable() {
            @Override
            public void run() {
                System.out.println("Print A");
            }
        };
        Runnable printB = new Runnable() {
            @Override
            public void run() {
                System.out.println("MESSAGE:" + " " + "Print B");
            }
        };
    
        class PrintMessage implements Runnable {
            private String msg;
            public PrintMessage(String msg) {
                this.msg = msg;
            }
    
            // overloaded constructor
            public PrintMessage(String prefix, String msg) {
                this.msg = prefix + " " + msg;
            }
    
    
            @Override
            public void run() {
                System.out.println(msg);
            }
        }
        Runnable printC = new PrintMessage("Print C");
        Runnable printD = new PrintMessage("Print D");
        Runnable printE = new PrintMessage("MESSAGE:", "Print E");
    
        public static void main(String[] args) {
            OuterClass sample = new OuterClass();
            sample.printA.run();
            sample.printB.run();
            sample.printC.run();
            sample.printD.run();
            sample.printE.run();
        }
    }
    

    There are two instances of Runnable implemented as anonymous classes. While printA is created you cannot use it to create printB. You should create anonymous class from the beginning (i.e. override all abstract methods).

    If an inner class created based on Runnable, you can use it in form new PrintMessage() to create new instances. Besides that it's possible to use non-default constructors.