Redefining static method in child class - java

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?

Related

Static method in parent class does not allow child to add a non static method?

The below code does not compile:
public class Child extends Parent{
void foo() {
}
}
class Parent{
public static void foo(){}
}
Why can't I declare a non static method in my child class? Overriding is not allowed in this case as the method is static, so why is the compiler not allowing us to declare an instance method?
Because Child Classes inherent all methods and fields from the Parent Class. In this case there will be two Child#foo() methods in the Child class since it would not have been overridden if this had had compiled.
That method has the same signature as the static method, and since you can't override static methods (and it is still a part of Parent, which Child still gets), you can't declare another foo with the same signature in a child method.
To be more technical, the JLS specifies:
It is a compile-time error for the body of a class to declare as members two methods with override-equivalent signatures (§8.4.2).
If you changed the signature; that is, if you declared an argument in the child class' method, then it would be okay.
You can't change access of inherited methods while overriding them - static stays static.
Same thing applies when overloading methods in single class - you can use same method name but methods need to accept different parameters.
Because the child recognize foo() from parent and itself. So you can't not create with your current code. However, you can declare new foo() in your child like this:
public class Child extends Parent{
public static void foo() {
}
}
class Parent{
public static void foo(){
}
}
More detail here: You can write a new static method in the subclass that has the same signature as the one in the superclass, thus hiding it.
http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html

why Exception or Error not generated when no main method found?

Ok just for sake knowledge , I tried below cases (Assume that Class A and B are in same package)
ClassA
public class ClassA {
public static void main(String[] args) {
System.out.println("A");
}
}
ClassB
public class ClassB extends ClassA {
public static void main(String[] args) {
System.out.println("B");
}
}
executing above ClassB it will produce output of B now after below change in classB
ClassB
public class ClassB extends ClassA {
//blank body
}
If I compile and run in terminal it gives me output A that was totally surprising as it should had given NoSuchMethodError as no main method was their so kindly explain the weird behavior ?
Note: Many answers contains Override word please use hiding as we cannot override static methods in java.
In the first case, you're hiding the main method since you're defining a new one in the subclass, in the second case you didn't you'll inherent A's main.
See The Java™ Tutorials - Overriding and Hiding:
If a subclass defines a static method with the same signature as a
static method in the superclass, then the method in the subclass hides the one in the superclass.
In Java subclasses inherit all methods of their base classes, including their static methods.
Defining an instance method in the subclass with the matching name and parameters of a method in the superclass is an override. Doing the same thing for static methods hides the method of the superclass.
Hiding does not mean that the method disappears, though: both methods remain callable with the appropriate syntax. In your first example everything is clear: both A and B have their own main; calling A.main() prints A, while calling B.main() prints B.
In your second example, calling B.main() is also allowed. Since main is inherited from A, the result is printing A.
public static void main(String[] args) is just a method which you inherit from A in second case.

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

Why am I getting method overriding error?

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.

trying to understand implicit superinterfaces

Sorry to bring back the dead. But I still don't clearly understand what this section of specification states.
If an interface has no direct superinterfaces, then the interface
implicitly declares a public abstract member method m with signature
s, return type r, and throws clause t corresponding to each public
instance method m with signature s, return type r, and throws clause t
declared in Object, unless a method with the same signature, same
return type, and a compatible throws clause is explicitly declared by
the interface. It is a compile-time error if the interface explicitly
declares such a method m in the case where m is declared to be final
in Object.
Given
interface Testing
{
void test();
}
public class Test{
public static void main(String[] args) {
Testing t = new Testing(){
#Override
public void test(){
}
};
t.test();
t.toString();
}
}
Now as the spec states that the above will change to
interface Testing
{
void test();
String toString();
//other non-final methods of Object
}
public class Test{
public static void main(String[] args) {
Testing t = new Testing(){
#Override
public void test(){
}
};
t.test();
t.toString();
}
}
Also. please confirm if there is an hierarchy of interfaces then all of them get these abstract methods.
What it means is that every class extends Object (at some point in its class heirarchy). However, interfaces do not extend Object. This is to avoid the problems that arise from multiple inheirtance.
Since interfaces do not extend Object that would mean we were unable to use methods like toString if the type (not class) of the object we had access to was an interface. But we know those methods must be available since all classes at some point extend from Object. Therefore, to get around this problem all of Object's not final methods are implicitly declared in all interfaces that have no superinterfaces. These contracts of these methods are always satisfied since all classes must at some point extend from Object.
TL;DR -- it's a trick to make sure we can access the methods made available by Object when we have an instance of some class stored in variable that's type is an interface (eg. Serializable)
edit: To answer your question, You're slightly off. All non-final methods of Object are added to an interface (whether they are used or not) if that interface has no parent interface AND for each method to added: that there is no matching method is explicitly declared by the interface.
As long as there is no super interface to an interface it gets the implicit declaration of the Object class methods. As long as these methods are included in the interface. Every interface that either extends or implements this interface doesn't see much difference between the methods that are explicitly declared by this interface or it got implicitly. That point forward that interface is as good as declared them explicitly.

Categories