Are private instance method not bounded at run time? - java

Please have a look at following code.
class TestClass{
private void privMethod()
{
System.out.println("TestClass Method");
}
public static void main(String... args)
{
TestClass obj=new SubClass();
obj.privMethod();
}
}
class SubClass extends TestClass
{
private void privMethod()
{
System.out.println("SubClass Method");
}
}
when I compile this code its gets compiled fine.
when I run TestClass, the output is: TestClass method
The ref. variable obj is of TestClass type but it is referring to a Sub class' object so at run time it should bind with Sub's privMethod().
Can you explain this?

private methods are not overriden by methods in a child class. Only public, protected and package-private ones can be overriden. Therefore polymorphism behavior at runtime is not applied.
If you add the annotation #Override to the declared method in the subclass, you would get a compilation error:
#Override // error
private void privMethod()
{
System.out.println("SubClass Method");
}

private modifier—the field/method is accessible only within its own class.
For more on access specifier.
So although the SubClass extends TestClassbut privMethod() of TestClass is not visible to the SubClass at all. So when you are implementing the privMethod() method in SubClass, it is not overriding the method of TestClass.
To make sure that you are overriding the method of the superclass, you can use #Override Java annotation.If the method does not match a method in the superclass, the compiler will give you the below error
The method privMethod() of type SubClass must override or implement a supertype method

Related

How to access a protected method of superclass in a subclass?

I have parent-child classes in two different packages. I am overriding a method of protected type. I want to access super class protected method in subclass.
Consider below code:
package package1;
public class Super
{
protected void demoMethod()
{
System.out.println("In super method");
}
}
package package2;
import package1.Super;
public class Sub extends Super
{
#Override
protected void demoMethod()
{
System.out.println("In sub method");
}
public static void main(String[] args)
{
//code for accessing superclass demoMethod to print "In super method"
}
}
In the main method of sub class, I want to access super class demoMethod which prints "In super method". I know demoMethod won't be visible from sub class using super class object reference to call demoMethod.
Is it possible or not? If yes, how?
Consider me new to Java and provide answers replacing comment in main method.
In the child class use super.demoMethod() or just remove it altogether from the child class
Your main() method cannot access the superclass implementation of demoMethod() -- because it's overridden in the child class.
Your main() method can access demoMethod(), through a reference of the subclass type, even though it's protected, because it's in the same package as your subclass. But it will call the subclass implementation.
But if you're "using superclass object reference to call demoMethod", the method will not be accessible, and your code will not compile. Your superclass is in a different package. Methods marked protected can only be accessed by subclasses and by code in the same package.
If you made the method public in both subclass and superclass, calling demoMethod() would call the subclass implementation, regardless whether the reference was of the super or subclass type.
An instance of the subclass can call super.demoMethod() as part of the implementation of its methods. But the main() method cannot.

Override "private" method in java

There something ambiguous about this idea and I need some clarifications.
My problem is when using this code:
public class B {
private void don() {
System.out.println("hoho private");
}
public static void main(String[] args) {
B t = new A();
t.don();
}
}
class A extends B {
public void don() {
System.out.println("hoho public");
}
}
The output is hoho private.
Is this because the main function is in the same class as the method don, or because of overriding?
I have read this idea in a book, and when I put the main function in another class I get a compiler error.
You cannot override a private method. It isn't visible if you cast A to B. You can override a protected method, but that isn't what you're doing here (and yes, here if you move your main to A then you would get the other method. I would recommend the #Override annotation when you intend to override,
class A extends B {
#Override
public void don() { // <-- will not compile if don is private in B.
System.out.println("hoho public");
}
}
In this case why didn't compiler provide an error for using t.don() which is private?
The Java Tutorials: Predefined Annotation Types says (in part)
While it is not required to use this annotation when overriding a method, it helps to prevent errors. If a method marked with #Override fails to correctly override a method in one of its superclasses, the compiler generates an error.
is this because the main function is in the same class as the method "don"
No, it's because A's don() is unrelated to B's don() method, in spite of having the same name and argument list. private methods are hidden inside their class. They cannot be invoked directly by outside callers, such as main method in your case, because they are encapsulated inside the class. They do not participate in method overrides.
No, a private method cannot be overridden since it is not visible from any other class. You have declared a new method for your subclass that has no relation to the superclass method. One way to look at it is to ask yourself whether it would be legal to write super.func() in the Derived class.
You can't override a private method, but you can introduce one in a derived class without a problem. The derive class can not access the private method on the ancestor.
Since t is a on object of type B, calling don() method will invoque the method defined at B. It doesn't even know that there is a method named also don() at class A
private members aren't visible to any other classes, even children
You can't override a private method, but then again, you can't call it either. You can create an identical method with the same name in the child however.
public class A
{
private int calculate() {return 1;}
public void visibleMethod()
{
System.out.println(calculate());
};
}
public class B extends A
{
private int calculate() {return 2;}
public void visibleMethod()
{
System.out.println(calculate());
};
}
If you call A.visibleMethod() it prints out 1.
If you call B.visibleMethod() it prints 2.
If you don't implement the private calculate() method in B, it won't compile because the public method that calls it can't see the private method in A.

Why static method of parent class is called when subclass has already overridden it?

I am confused by the behaviour of the static method when it is overridden in the subclass.
Below is the code:
public class SuperClass {
public static void staticMethod() {
System.out.println("SuperClass: inside staticMethod");
}
}
public class SubClass extends SuperClass {
//overriding the static method
public static void staticMethod() {
System.out.println("SubClass: inside staticMethod");
}
}
public class CheckClass {
public static void main(String[] args) {
SuperClass superClassWithSuperCons = new SuperClass();
SuperClass superClassWithSubCons = new SubClass();
SubClass subClassWithSubCons = new SubClass();
superClassWithSuperCons.staticMethod();
superClassWithSubCons.staticMethod();
subClassWithSubCons.staticMethod();
}
}
Below is the output which we are getting :
1) SuperClass: inside staticMethod
2) SuperClass: inside staticMethod
3) SubClass: inside staticMethod
Why static method of superclass gets called here in the second case?
If method is not static, then according to polymorphism, method of the subclass is called when subclass object is passed on runtime.
static method resolution is always based on the Reference type.
The code
superClassWithSuperCons.staticMethod();
superClassWithSubCons.staticMethod();
subClassWithSubCons.staticMethod();
is converted to this after compilation
SuperClass.staticMethod();
SuperClass.staticMethod();
SubClass.staticMethod();
Accroding to this it is the call to SuperClass method not the subclass method.So you are getting the output of SuperClass method.
A method declared static cannot be overridden but can be re-declared. That's the answer.
A static method is not associated with any instance of a class so the concept is not applicable. Try the same with not static and you'll see the difference.
Your question is duplicated actually:
Why doesn't Java allow overriding of static methods?
Interesting question. I'm not familiar with the underlying mechanisms, but it seems that for static methods, the declared type (in your middle example, SuperClass), not the actual type SubClass is considered for resolving the method call. It actually makes sense because you're not looking at the actual instance of an object when calling a static function.
Static methods are redefined not overridden...
If you try to override the static method then it will be treated as a non overridden method of the sub class.
Static methods will be called based on the type of the reference not the object created.
For more information visit the page.
http://javaunturnedtopics.blogspot.in/2016/07/static-methods-are-redefined-not.html

java non-static to static method -- hiding or overriding

is re-defining a non-static method in a subclass with the same everything but as static overriding or hiding it ?
http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html says hiding. but when i declare the superclass method as final, i get an override error.
superclass declaration is
final static void display() { ... }
subclass:
void display() { ... }
gives override error.
Is re-defining a non-static method in a subclass with the same everything but as static overriding or hiding it?
It's neither, because doing so triggers a compilation error, rendering your program invalid.
class A {
void x();
}
class B extends A {
// ERROR!!!
static void x();
}
Hiding happens when both methods in the pair are static methods; overriding happens when both methods in the pair are instance methods. When one of the two is a static method and the other one is an instance method, Java considers it an error. It does not matter if the instance method is final or not; it also does not matter if the static method is in the base or in the derived class: Java calls it an error either way.
The compiler message that says "cannot override" is misleading, though: I think that "name collision" would have been a better name for such conditions, because "overriding" is reserved for situations with two instance methods.
The method you describe is an instance method, not a static method. You cannot hide instance methods, only static methods. An instance method declared final cannot be overridden in a subclass, and this is what you are trying to do.
final static void display() { ... }
The above method is having non-access modifier final, and a method which has been made final can't be overridden.
How can you override a method that is final.
The final methods can never be overrided in the subclass.
That is the compilation error..
You can't override a final method...
Ex:
class Super
{
final void display()
{
//do something
}
void show()
{
//Do Something
}
}
class Sub extends Super
{
//Not Valid hence Compile Error
void display()
{
//do something
}
//Valid
void show()
{
//Do Something
}
}

why should we widen the accessibility of overridden methods?

why should we widen the accessibility of overridden methods ? If the super class has a protected method and subclass has same method with public. Why should happen?
It's a different method! Subclasses don't inherit private methods! So you're not "overriding" at all. You are simply DEFINING a method with the same name as the private method in the superclass.
class A
{
private void myMethod() { }
}
class B extends A
{
public void myMethod() { } // a completely different method. Has nothing to do with the above method. It is not an override.
}
Because in an object hierarchy, JVM will always run the Overriden method. If your overriden method is not accessible, then it is useless.
public class A{
void A(){}
}
public class B extends A{
private void A(){} //this makes no sence and its impossible
PSV main(String ..){
A a = new B();
a.A(); //error as JVM cannot call overriden method which is private.
}
}
Methods declared as private or static can not be overridden!
Annotation #Override indicates that a method declaration is intended to override a method declaration in a superclass. If a method is annotated with this annotation type but does not override a superclass method, compilers are required to generate an error message.
Use it every time you override a method for two benefits. This way, if you make a common mistake of misspelling a method name or not correctly matching the parameters, you will be warned that you method does not actually override as you think it does. Secondly, it makes your code easier to understand because it is more obvious when methods are overwritten.
And in Java 1.6 you can use it to mark when a method implements an interface for the same benefits.

Categories