THis is my superclass:
class Superclass {
int a=89;
final static void m( int p){
System.out.println("Inside superclass");
}
static void n(){
system.out.print("superclass");
}
}
This is my subclass::
class Subclass extends Superclass {
int a=90;
static void m( int p){
System.out.println("Inside subclass");
}
static void n(){
system.out.print("subclass");
}
}
Main class:
class main {
public static void main(String[] args) {
Subclass.m(89);
new Subclass().n();
}
}
the problem is that i cannot understand why Javac is giving me overriding error in static method..an P.S plzz elaborate that all rules for overriding are also valid for hiding. like
The new method definition must have the same method signature (i.e.,
method name and parameters) and the same return type. Whether
parameters in the overriding method should be final is at the
discretion of the subclass method's signature does not encompass the
final modifier of parameters, only their types and order.
The new
method definition cannot narrow the accessibility of the method, but
it can widen it The new method definition can only specify all or
none, or a subset of the exception classes (including their
subclasses) specified in the throws clause of the overridden method in
the superclass
my error is:
run:
Exception in thread "main" java.lang.RuntimeException: Uncompilable
source code - m(int) in javaapplication3.Subclass cannot override
m(int) in javaapplication3.Superclass overridden method is
static,final at javaapplication3.Subclass.m(JavaApplication3.java:18)
at javaapplication3.min.main(JavaApplication3.java:25) Java Result: 1
also i want to ask if static members called from classname to resolve whicch version of method is executed when method is hidden by subclass extending the superclass
what if i make anonymous object and then call method then how the compiler determines which version of method should be called.
in above code in main class i type this: new Subclass().n();
how does the compiler know subclass version of method should be called even if i am not providing the type of reference variable
From the JLS 8.4.3.3:
A method can be declared final to prevent subclasses from overriding or hiding it.
Static methods with the same signature from the parent class are hidden when called from an instance of the subclass. However, you can't override/hide final methods.
The keyword final will disable the method from being hidden. So they cannot be hidden and an attempt to do so will result in a compiler error. There is a nice explanation on this on Javaranch.
What you are observing here is in accordance with JLS 8.4.3.3 which states that:
It is a compile-time error to attempt to override or hide a final
method.
You are trying to override final static void m method in subclass , which is not permitted by Java compiler.
Related
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
So I know that in Java when you have a static method you are supposed to call it with the format ClassName.method() rather than use the same structure as you would for instance methods, namely:
ClassName myObject = new ClassName();
myObject.method();
However, if you were to do it this way it would still be valid code and would work. Let's say I decide to do this where the method in question is static, and have the following setup:
public SuperClass {
public static int foo(int x) {
return x;
}
}
public SubClass extends SuperClass {
public static int foo(int x) { // Overriding foo() in SuperClass
return x + 1;
}
}
public MyDriver {
public static void main(String[] args) {
SuperClass myObject = new SubClass(); // Upcasting.
System.out.println(myObject.foo(5)); // This should polymorphically print 6
}
}
What prints out on the screen, however, is 5 rather than 6. Why?
Static methods apply only to the class they are defined in, and they cannot be overridden.
When you call myObject.foo(5), you are calling SuperClass.foo(5) in reality, because you declared myObject as a SuperClass, regardless of whether you instantiated it as one.
The proper way to call a static method is to call it directly from the class it is declared in, so if you wanted to call SubClass.foo(), you must call it from an explicitly declared SubClass instance (meaning no upcasting), or you need to call SubClass.foo() like so.
The simple answer is that calling static methods from instances evaluates to calling those same methods from the declared type with no instance rather than the instance type.
I am not certain of this, but I would not be surprised if when the code is compiled into byte-code, that the instance static method call would actually be compiled into a direct call to the declared type.
Edit: An upvote brought my attention back to this and I cleaned up the explanation to make it more clear and fix some negligible grammatical mistakes on my part. I hope this helps future readers.
Using instances of a class to call that class's static methods is something you should avoid, since it can cause confusion. If you need to call any method polymorphically, make it an instance method. You cannot polymorphically call a static method. The reason the SuperClass invocation is called is because that is the apparent class of myObject at compile-time. This effect can also be seen in the following scenario:
public void doSomething(SuperClass param) {
System.out.println("SuperClass");
}
public void doSomething(SubClass param) {
System.out.println("SubClass");
}
public void test() {
SuperClass myObject = new SubClass();
doSomething(myObject);
}
If test() is called, SuperClass will be printed.
Static methods don't depends on the instance, they belong to the class and only to the class, in fact if you have a static method you'll always access to one unique instance always.
myObject.foo(5)
is only a shortcut, what you really are doing is
SuperClass.foo(5)
Static methods are treated as global by the JVM, they are not bound to an object instance at all. By the way, you can only overload static methods, but you can not override. So check for "Oracle Documentation for Overriding and Hiding Documents".
Defining a Method with the Same Signature as a Superclass's Method:
-----------------------------------------Superclass Instance MethodSuperclass Static Method
Subclass Instance Method Overrides Generates a compile-time error
Subclass Static Method Generates a compile-time error Hides
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
}
}
It is written everywhere that static method cannot be overriden, but when I try to reduce the access specifier say from public to protected it gives an error. for example
public class StaticOverrideFunda {
public static void foo(){
System.out.println("Parent Foo");
}
}
public class B extends StaticOverrideFunda{
protected static void foo(){
System.out.println("Child Foo");
}
/**
* #param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
B.foo();
}
}
It says
Cannot reduce the visibility of the inherited method
So insense it is following the overriding rules, how come we are saying foo is not being overridden in B class? Why do we say it is hiding/shadowing and not overriding?
It's following some of the same rules as overriding, but that doesn't mean it is overriding. In this case, it's the rules in section 8.4.8.3 of the JLS, "Requirements in Overriding and Hiding":
The access modifier (§6.6) of an overriding or hiding method must provide at least as much access as the overridden or hidden method, as follows: [...]
It's still not overriding, as the method wouldn't be invoked polymorphically - you can't write a call which will sometimes end up calling StaticOverrideFunda.foo and sometimes end up calling B.foo; the target is determined entirely at compile time.
It would be worth reviewing the rest of section 8.4.8, which defines overriding as being something which occurs on instance methods.
You yourself posted answer in your question, overriding means having different code in child class for same method. As static methods cannot be overridden you cannot play with the visibility by modifying access specifiers.
I would like to know the reason why this is first allowed in Java (or oops in general)
I remember that the static methods are common for both parent and child class
public class Redefine extends Parent{
public static void test () {
}
}
class Parent{
public static void test () {
}
}
Q1 : Since Overriding is not supported for static methods , how can both classe contain same methods ?
Q2 : If change the method in static to throw an exception not defined its not compiling.
why is the case. Its obviously not overriding so i should be allowed to throw new exceptions right ?
public class Redefine extends Parent{
public static void test () throws Exception{
}
}
A1:: static method are per-class. They have nothing to do with inheritance hierarchies in terms of polymorphism. So calling Parent.test() will call the parent method, while calling Redefine.test() will call the child.
A2: JLS 8.4.8 writes:
If a class declares a static method m, then the declaration m is said to hide any method m', where the signature of m is a subsignature (§8.4.2) of the signature of m', in the superclasses and superinterfaces of the class that would otherwise be accessible to code in the class.
A method declaration must not have a throws clause that conflicts (§8.4.6) with that of any method that it overrides or hides; otherwise, a compile-time error occurs.
you arent overriding it, you are hiding it
http://faq.javaranch.com/java/OverridingVsHiding
what exception are you getting?
Q1: Static methods are not overridden, so these are two different methods with the same signature. One is called with Parent.test(), the other is called with Redefine.test()
Q2: Your method seems valid. What error do you get?