This question already has answers here:
Java superclass calls subclass method
(5 answers)
Closed 1 year ago.
Why does method() call the overridden subclass method2 instead of method2 in the BaseClass?
public class BaseClass {
public void method(){
System.out.println("method() called");
method2();
}
public void method2(){
System.out.println("method2() called");
}
}
public class ChildClass extends BaseClass {
public void method2(){
System.out.println("method2() from BaseClass");
}
}
public class Main {
public static void main(String[] args) {
ChildClass obj = new ChildClass();
obj.method();
}
}
This is the concept of Runtime polymorphism (Dynamic Method Dispatch). Because you are assigning the object (instance) of ChildClass to obj reference variable, it will call the method of child class.
Always the method of the class whose instance is created gets called first. If that method is not present in that particular child class, then the parent's inherited method gets called.
If you come from the C++ corner:
all instance methods (non-static) in Java are virtual.
All class methods (static) are NOT.
This is why your case happens.
This is also, why the Java compiler will complain (warn) that if you access a static method via an object, that you should call via the distinct class, because calls to the "static method of a object" could be ambiguous, because it could be two static methods with the same signature that get called.
Extending your Example:
package stackoverflow.staticcalls;
public class BaseClass {
public void method() {
System.out.println("method() called");
method2();
}
public void method2() {
System.out.println("method2() called");
}
static public void sayHello() {
System.out.println("BaseClass.sayHello()");
}
}
and
package stackoverflow.staticcalls;
public class ChildClass extends BaseClass {
public void method2() { // compiler warning: The method method2() of type ChildClass should be tagged with #Override since it actually overrides a superclass method
System.out.println("method2() from BaseClass");
}
public void originalCallToBaseMethod2() {
super.method2(); // will run BaseClass.method2()
}
static public void sayHello() {
System.out.println("ChildClass.sayHello()");
}
}
and
package stackoverflow.staticcalls;
public class Main {
public static void main(final String[] args) {
final ChildClass obj = new ChildClass();
System.out.println("\nCalling obj.method(); ...");
obj.method();
System.out.println("\nCalling obj.sayHello(); ...");
obj.sayHello(); // compiler warning: The static method sayHello() from the type ChildClass should be accessed in a static way
System.out.println("\nCalling ChildClass.sayHello(); ...");
ChildClass.sayHello(); // the proper call
System.out.println("\nCalling BaseClass.sayHello(); ...");
BaseClass.sayHello(); // but you can also explpicitly call the other method
System.out.println("\nCalling obj.originalCallToBaseMethod2(); ...");
obj.originalCallToBaseMethod2(); //
}
}
Here you see the examples to what I said.
Note: In the last call in Main.main() we still can call BaseClass.method2(), but not directly. We have to be within ChildClass to do that, and it's done via the super keyword/reference.
A little off-topic note, to complete addressing patterns:
If you're inside an inner class and need to call to a overshadowed name in the outer class, you can use Outer.this.method():
package stackoverflow.staticcalls;
import stackoverflow.staticcalls.OuterInner.Outer.Inner;
public class OuterInner {
class Outer {
void method() {
System.out.println("OuterInner.Outer.method()");
}
class Inner {
void method() {
System.out.println("OuterInner.Outer.Inner.method()");
}
void callOuter() {
Outer.this.method();
}
}
}
public static void main(final String[] args) {
final OuterInner oi = new OuterInner();
final Outer outer = oi.new Outer();
final Inner inner = outer.new Inner();
System.out.println("\nCalling inner.method(); ...");
inner.method();
System.out.println("\nCalling inner.callOuter(); ...");
inner.callOuter();
}
}
Related
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 1 year ago.
Improve this question
public class OuterMain {
public static void main(String[] args) {
Outer outer = new Outer();
outer.m2();
}
}
class Outer {
public void m1() {
class Inner {
void display() {
System.out.println("msg is displayed");
}
}
Inner inn = new Inner();
//cannot write code to call display() here
}
public void m2() {
//inner.display();
}
}
Above is the code block where there is a method local inner class. The display method inside the inner class prints a message. The main class creates an instance of Outer and calls m2(). I was asked to do modification, apply any concept in java but the task is to call the Inner class' display() method from m2(). Only restriction is that the method cannot be made static.
One thing you can do is use a private interface and make Inner implement it, thus enabling m2() to return an object with a display() method that can be called elsewhere in the same outer class
class Outer {
public Displayable m1() {
class Inner implements Displayable {
#Override
public void display() {
System.out.println("msg is displayed");
}
}
return new Inner();
}
private interface Displayable {
void display();
}
public void m2() {
m1().display();
}
}
There are three issues here
The type Inner is not visible to m2()
The instance of Inner created in m1() is not visible to m2()
The method m1() is never invoked.
The purpose of local classes is precisely to reduce the visibility of the class and its instances and to avoid creating the instances when the method has not been invoked. Even the initialization of Inner should be deferred until the method m1() creates the first instance of it.
A solution not perverting those properties would be
class Outer {
private Runnable accessor;
public void m1() {
class Inner {
void display() {
System.out.println("msg is displayed");
}
}
Inner inn = new Inner();
accessor = inn::display;
}
public void m2() {
m1();
accessor.run();
}
}
Here, m1() doesn't invoke display but provides access to it using a standard interface, without giving away any information about its internals. m2() invokes the method m1() to get the access followed by invoking the standard interface method.
In Java, we can write a class within a method and this will be a local type. Like local variables, the scope of the inner class is restricted within the method.
A method-local inner class can be instantiated only within the method where the inner class is defined. The following program shows how to use a method-local inner class
instantiate the class at proper point.
I will show you the code*
package com;
public class Outer{
public void m1() {
class Inner {
public void display(){
System.out.println("display from inner class");
}
}// end of inner class
// Accessing the inner class
Inner inner = new Inner();
inner.display();
}//m1 ends here
public static void main(String[] args) {
Outer outer=new Outer();
outer.m1();
}
}
With the help of interface the inner class method can be access as per your requirement :
class OusterMain{
public static void main(String[] args) {
OuterClass oc = new OuterClass();
oc.methodTwo();
}
}
class OuterClass {
public InnerInterface methodOne() {
class InnerClass implements InnerInterface{
#Override
public void display() {
System.out.println("Print message.");
}
}
// this reference is used to call display() method inside methodTwo()
return new InnerClass();
}
private interface InnerInterface{
void display();
}
public void methodTwo() {
methodOne().display();
}
}
Using reflection you can achieve this goal easily.
Here com.problem.solution is my package name. Replace it with your package name.
Get the outer and inner class object associated with the class or interface with the given string name.
Like - forName("com.problem.solution.Outer");
Then try to access inner class using - Class.forName("com.problem.solution.Outer$1Inner");
In java reflection, you can access any inner class using OuterClass$1InnerClass this type of syntax.
Then construct object, then pick your desired method and then invoke that method.
Complete code:
//package com.problem.solution;
import java.lang.reflect.Constructor;
import java.lang.reflect.Method;
public class OuterMain {
public static void main(String[] args) {
Outer outer = new Outer();
outer.m2();
}
}
class Outer {
public void m1() {
class Inner {
void display() {
System.out.println("msg is displayed");
}
}
Inner y = new Inner();
}
public void m2() {
try {
Class<?> enclosingClass = Class.forName("com.problem.solution.Outer");
Object enclosingInstance = enclosingClass.newInstance();
Class<?> innerClass = Class.forName("com.problem.solution.Outer$1Inner");
Constructor<?> ctor = innerClass.getDeclaredConstructor(enclosingClass);
Object innerInstance = ctor.newInstance(enclosingInstance);
Method someMethod = innerInstance.getClass().getDeclaredMethod("display");
someMethod.setAccessible(true);
someMethod.invoke(innerInstance);
} catch (Exception ex) {
ex.printStackTrace();
}
}
}
Output:
msg is displayed
This is my java code:
class A {
interface That {
void show();
}
}
class B implements A.That {
public void show() {
System.out.println("Hi");
}
}
public class MainClass {
public static void main(String args[]) {
A obj = new A();
obj.That object = new B();
object.show();
}
}
Since A is a class (not abstract) we can create its instance and than we can use members of that instance. Now interface is member so obj.That should work but javac says that obj.That is not package. Why?
Interfaces are always static when nested in a class. You should therefore access your interface declaration as A.That, not obj.That.
As I have gone through some of the programming sites which explains anonymous inner class in java.
But, I still have doubts that how it really works and on the conclusions which I made below.
Here is code :
public class Implementing {
public static void main(String[] args) {
SuperClass a = new SuperClass() { // ... 1st
public void call () { // ... 2nd
System.out.println("Method call");
}
public void call2 () { // creating new method in anonymous inner class
System.out.println ("New call2 Method in Anonymous Class");
}
};
a.call(); // ... 3rd
try {
a.getClass().getMethod("call2",null).invoke(a,null); // ... 4th
} catch (Exeception e) {
System.out.println(e);
}
}
}
class SuperClass {
public void call() {
System.out.println("Super Class");
}
}
What I understand is this :
At 1st :-
Anonymous inner class is sub-class.
we are creating instance of anonymous inner class as well as we
are extending the class SuperClass.
we are running constructor of SuperClass, but we created object
of anonymous class of type SuperClass.
polymorphism at work.
Actually, we are doing this at 1st :
* 1. anonymousClass extends SuperClass
* 2. anonymousClass a = new SuperClass()
* 3. { }; // our anonymous class field
At 2nd : - overrides SuperClass call Method().
At 3rd : - calling call() Method by object 'a'.
At 4th : - accessing new method call2() Method in anonymous inner class.
So, my these conclusions are right or wrong ? If wrong why they are wrong ? Please Explain.
Your code creating an Anonymous Class:
public static void main(String[] args) {
SuperClass a = new SuperClass() { // ... 1st
public void call() {
System.out.println("Method call");
}
public void call2() {
System.out.println("New call2 Method in Anonymous Class");
}
};
...
}
is the same as this code creating a Local Class:
public static void main(String[] args) {
class LocalClass extends SuperClass {
public void call() {
System.out.println("Method call");
}
public void call2() {
System.out.println("New call2 Method in Anonymous Class");
}
}
SuperClass b = new LocalClass();
...
}
except that the class is unnamed, aka anonymous.
Since you're doing this from a static method, and you're not using any local variables, they are both the same as this Static Nested Class:
static class NestedClass extends SuperClass {
public void call() {
System.out.println("Method call");
}
public void call2() {
System.out.println("New call2 Method in Anonymous Class");
}
}
If you look at the compiled .class files, you'll see they are all just classes:
SuperClass.class <-- Your superclass
Implementing.class <-- Your main class
Implementing$1.class <-- Anonymous class
Implementing$1LocalClass.class <-- Local class
Implementing$NestedClass.class <-- Nested class
I know that private methods are hidden in Derived class and they cant be overridden but my question is different.. Please go through the following problem. My question is mentioned in the problem stated below:
TestPolymorphism.java
class CheckParent {
private void display() {
System.out.println("This is parent class");
}
}
class CheckChild extends CheckParent {
void display() {
System.out.println("This is child class");
}
}
public class TestPolymorphism {
public static void main(String[] args) {
CheckParent cp = new CheckChild();
cp.display(); // This will throw error as display() method id private
// and invisible to child class
}
However, in following code snippet no exception is thrown.
CheckParent.java
public class CheckParent {
private void display() {
System.out.println("This is parent class");
}
public static void main(String[] args) {
CheckParent cp = new CheckChild();
cp.display(); /*This will print "This is parent class" without any error
* my question is why no error is thrown like above case
* as here too display() method is private and invisible to
* derived class */
}
}
class CheckChild extends CheckParent {
void display() {
System.out.println("This is child class");
}
}
}
For constructor, private, final or static methods static(early) binding is used. For all others dynamic(late) binding is used. Check this out:
http://geekexplains.blogspot.co.uk/2008/06/dynamic-binding-vs-static-binding-in.html
If you would like to override a parent class method please consider placing the #Override annotation in front of the overriding method, so that compiler can warn you of possible mistakes.
I do not think you are overriding the display() method of a parent class with display() method of a child class, because the parent class's method is private. You are rather defining an new method.
class CheckParent {
//remove private access modifier to have the method overriden in child class
private void display() {
System.out.println("This is parent class");
}
}
class CheckChild extends CheckParent {
#Override //IDE or compiler will warn you that you are not overriding anything
void display() {
System.out.println("This is child class");
}
}
Please see Bloch's Effective Java. 2nd Edition, Item 36.
In the second code snippet you create CheckChild instance but store is as CheckParent accessing the private void display() of CheckParent instance method inside the CheckParent class's static method. Class members (static method in your case) can access it's private methods and fields, so this code is valid.
If you want to access the instance void display() method of the CheckChild class instance in the second code snippet you should cast the CheckParent instance to CheckChild first.
public class CheckParent {
private void display() {
System.out.println("This is parent class");
}
public static void main(String[] args) {
CheckParent cp = new CheckChild();
cp.display(); //"This is parent class"
if (cp instanceof CheckChild){
((CheckChild) cp).display(); //"This is child class"
}
}
}
class CheckChild extends CheckParent {
void display() {
System.out.println("This is child class");
}
}
Anyway such coding approach looks like a misuse of inheritance to me.
I'm not sure if my question title describes my situation aptly, so my apologies if it doesn't! Anyway, let's say I have the following code snippet (visibility is as stated):
public class ChildClass extends ParentClass {
// more code
private void myMethod() {
MyClass mine = new MyClass() {
public void anotherMethod() {
// insert code to access a method in ParentClass
}
};
}
}
Is it possible for code within anotherMethod() to access a protected method found in ParentClass? If so, how can this be done?
I've tried something like...
(ParentClass.this).parentMethod();
...but obviously it doesn't work due to scope issues.
This compiles fine:
class MyClass {
}
class ParentClass {
protected void parentMethod() {
}
}
class ChildClass extends ParentClass {
private void myMethod() {
MyClass mine = new MyClass() {
public void anotherMethod() {
parentMethod(); // this works
}
};
}
}
A non-static inner class can access all methods of the enclosing class as if it were it's own methods:
public class Test {
public int getOne() {
return 1;
}
public class Inner {
public int getEnclosingOne() {
return getOne(); // this works...
}
}
}
A static inner class can not, as a static inner class is not bound to an instance of the parent class. That can only call static methods on the enclosing class.
As for methods when taking into account inheritance, an method in a non-static inner class can use all the methods of the enclosing (outer) class.
The interesting part is Test2.super.getOne() which indeed obtains getOne() from Test2.super, which is a Test. This is just like Test2 would access the method, namely using super though prefixed with Test2 to indicate you're accessing the namespace of the outer class.
public class Test2 extends Test {
public int getInnerOuterParentOne() {
Inner2 inner2 = new Inner2();
return inner2.getOuterParentOne();
}
public int getInnerOuterOne() {
Inner2 inner2 = new Inner2();
return inner2.getOuterOne();
}
public int getOne() {
return 2;
}
public class Inner2 {
public int getOuterOne() {
return getOne();
}
public int getOuterParentOne() {
return Test2.super.getOne();
}
}
public static void main(String[] args) {
Test2 test2 = new Test2();
System.out.println(test2.getInnerOuterOne()); // 2
System.out.println(test2.getInnerOuterParentOne()); // 1
}
}
There is no way to access "parent class method" in Java, irrelatively to visibility (except for super.parentMethod() in subclass's parentMethod()).
That is, if ChildClass overrides parentMethod(), there is no way to call ParentClass.parentMethod() (bypassing ChildClass.parentMethod()) from other methods of ChildClass.
However, if ChildClass doesn't override parentMethod(), that method is inherited by ChildClass, so that you can access it as a ChildClass's method, i.e. simply as parentMethod().