Reputation: 4475
public class First {
public void methodOne() {
System.out.println("in Parent methodOne");
}
public void methodTwo() {
System.out.println("in Parent methodTwo");
}
}
public class Second extends First{
private void methodOne() {
System.out.println("methodOne");
}
@Override
public void methodTwo() {
System.out.println("methodTwo");
}
public static void main(String[] args) {
First first = new Second();
first.methodOne();
}
}
Here in the Second class , We have a private method "methodOne". This shows an error in eclipse as "Cannot reduce the visibility of the inherited method from First".
I know this error is because overriding method should not reduce the visibility
Even though that it shows a compilation error, it executes fine and gives the output as in Parent methodOne
. If it is a compilation error, why it is producing the output?
When i change the access specifier to protected, it gives the expected compilation error in the console!
Upvotes: 1
Views: 285
Reputation: 1405
If you check Class Second
using decompiler
,methodOne
will be as below
private void methodOne()
{
throw new Error("Unresolved compilation problem: \n\tCannot reduce the visibility of the inherited method from First\n");
}
Since Reference is of parent class and method is visible ,the parent method gets called.
Eclipse compiler identifies methodOne
is overridden method of parent and should follow overridden methods rules.
Java builder concepts -Eclipse
Upvotes: 2
Reputation: 9291
Yes, I could recreate the issue in Spring Tool Suite Version: 3.7.0.RELEASE. Although there is an error pending, when forced to run although there are errors, the in Parent methodOne output occurs. Eclipse may be ignoring the error code block, since it is forced to execute.
I executed the following code,
class First {
public void methodOne() {
System.out.println("in Parent methodOne");
}
public void methodTwo() {
System.out.println("in Parent methodTwo");
}
}
public class Second extends First{
// private void methodOne() {
// System.out.println("methodOne");
// }
@Override
public void methodTwo() {
System.out.println("methodTwo");
}
public static void main(String[] args) {
First first = new Second();
first.methodOne();
}
}
and I got in Parent methodOne as the output.
In the code you're assigning the object to a reference of it's parent.
First first = new Second();
Since the class Second
doesn't have a method as methodOne
, the methodOne
method in the First
class is called.
Assume you declare the methodOne
in the second as Public
.
Then you would get methodOne as the output.
When overriding,
Consider the following example.
class ABCD {
int x = 10;
static int y = 20;
public String getName() {
return "ABCD";
}
}
class MNOP extends ABCD {
int x = 30;
static int y = 40;
public String getName() {
return "MNOP";
}
}
public static void main(String[] args) {
System.out.println(new MNOP().x + ", " + new MNOP().y);
ABCD a = new MNOP();
System.out.println(a.x); // 10
System.out.println(a.y); // 20
System.out.println(a.getName()); // MNOP
}
Hope this helps.
Upvotes: 1
Reputation: 3736
I think thats the "magic" of the Eclipse Compiler, it tries to compile it anyway.
This Example runs fine, since at runtime, the buggy Method compileError
never gets called:
public class EclispeCompilerErrorExample {
public static void main(String[] args) {
if(false) {
compileError();
}
else {
System.out.println("But run anyways");
}
}
private static void compileError() {
int i = "this wont comppile";
}
}
Your example with private
works, since your Method never get called (its a private Method, inaccessible for the First
-Object-Reference), so the First.methodOne
gets called. When its protected
ists actually "reachable" for the code, and therefore throw an Exception.
Upvotes: 1
Reputation: 79
If u wanna override a method in the sub class,the scope of the specified method modifier in the sub class must greater than the base class. Just like ur programe,the method methodOne's modifier in the class Second must be public.
Upvotes: -2