please explain why? can't find any good source
interface ABCD {
default void print() {}
static void print_static() {}
}
interface B extends ABCD{
static void print() {}//error, why?
default void print_static() {}//fine, why?
}
Answer:
#AdolisPali Becase the default method print is inherited from ABCD, so it's in interface B too. And you can't have a static method in that interface with the same name and arguments – fps
You cannot override the static method of the interface; you can just access them using the name of the interface. If you try to override a static method of an interface by defining a similar method in the implementing interface, it will be considered as another method.
See this: https://www.tutorialspoint.com/default-method-vs-static-method-in-an-interface-in-java#:~:text=You%20cannot%20override%20the%20static,static)%20method%20of%20the%20class.
Essentially in Java, the keyword static indicates that the particular member belongs to a type itself.
Every instance method automatically inherits to their sub classes and only can be overridden by instance method from their sub classes too. Static method can not override instance method. Thus in your case, method "default void print_static()" from ABCD doesn't override "static void print_static()" from B. You still can call ABCD.print_static() for ABCD and print_static() for B.
Related
While refactoring I came across the following method in a subclass:
public void disposeResultsTable() {
super.disposeResultsTable();
}
What are the benefits to keeping this method rather than simply allowing the inherited superclass method to be called?
The only technical reason I can think of is what Michael proposed in the comments - making a restricted method become public.
However, I can think of a few human reasons.
For instance, this could be a convenient place to place a breakpoint for debugging invocations of disposeResultsTable of the child class. Or perhaps this was meant as a placeholder - "remember to implement this method for this class", or maybe someone wanted to explicitly point out to the reader of this code that this class uses the parent's implementation of disposeResultsTable. There are probably a bunch more options.
Have you tried looking up the history of this piece of code in the VCS? Maybe there's a helpful commit message from the original author.
The answer by Malt shows a common reason for overriding a method trivially by only calling the super implementation, namely to change the visibility from protected to public. Whether or not this might be the case in your example depends on the visibility of the respective method in the superclass...
However, there is another possible reason - although it might be a bit far-fetched and unusual - and this possible reason is reflection: The Class#getDeclaredMethods method only returns the methods that are... well, declared in this class.
For example, consider the following program:
import java.lang.reflect.Method;
public class TrivialOverride
{
static class BaseClass
{
void method0() {}
void method1() {}
}
static class ChildClass extends BaseClass
{
void method0() {}
}
public static void main(String[] args)
{
printDeclaredMethods(BaseClass.class);
printDeclaredMethods(ChildClass.class);
}
private static void printDeclaredMethods(Class<?> c)
{
System.out.println("Declared methods in " + c.getSimpleName());
for (Method m : c.getDeclaredMethods())
{
System.out.println(m.getName());
}
System.out.println();
}
}
The output is
Declared methods in BaseClass
method0
method1
Declared methods in ChildClass
method0
So method0 only appears in the list of declared methods of the child class because it was overridden from the base class.
class Base {
public static void staticMethod(Base bObj) {
System.out.println("In Base.staticMethod()");
bObj.instanceMethod();
}
public void instanceMethod() {
System.out.println("In Base.instanceMethod()");
}
}
class Derived extends Base {
public static void staticMethod(Base bObj) {
System.out.println("In Derived.staticMethod()");
bObj.instanceMethod();
}
public void instanceMethod() {
System.out.println("In Derived.instanceMethod()");
}
}
public class Main {
public static void main(String []args) {
Base bObj = new Derived();
bObj.staticMethod(bObj);
}
}
Initially, when I saw this example I was sure that the result would be:
"In Base.staticMethod()"
"In Base.instanceMethod()".
After the initialization of the first Derived object it is obvious that it will be interpreted as a Base object due to upcast and it will call the static method of the base class which it does but later when it calls the other method(instance method) it goes inside the derived function instead of base class.
Why, considering that initially it was considered being Base?
There is no method overriding for static methods. Therefore bObj.staticMethod(), which is equivalent to Base.staticMethod, invokes the static method of the base class.
Inside the static method you are calling bObj.instanceMethod(). For instance methods there is method overriding, and the runtime type of bObj determines which method is executed - the instance method of Derived in your case.
Override is only for instance methods. For Static Method the term is called Method Hiding See Detail.
1. If method hiding is used then BaseClass's method is hidden from Subclass. method selection solely depends on which class's reference you are using to call the method. In your example since you are using BaseClass (even you assign Subclass object, it still on the class level it's BaseClass) reference to make a call to the static method it makes a call to BaseClass's method. If you would use SubClass reference as below then it would call the SubClass's static method
public static void main(String []) {
Derived bObj = new Derived();
bObj.staticMethod(bObj);
}
As the call inside the static method is for an Instance method. It uses polymorphism here and calls the SubClass's method.
TL;DR:
bObj.staticMethod(bObj); only looks at the compile-time type of bObj, and is equivalent to Base.staticMethod(bObj); in your case. There's no overriding.
bObj.instanceMethod(); only looks at the runtime class of bObj, and selects the method based on that class. So overriding works here.
Explanation
If you call a static method, you should do so by naming the class, not an instance. So bObj.staticMethod(bObj) should better be written Base.staticMethod(bObj). Typically, the compiler will issue a warning for the first version.
That's because the runtime instance is irrevant for selecting the static method. The decision is made by the compiler. And that's why we call this method type "static", because it lacks the dynamic method lookup of instance methods. That means that there is no overriding based on the instance "before the dot".
Using an instance expression misleads the reader into thinking the instance were relevant, and therefore should not be used. And inside the static method, there is no way to refer to the instance "before the dot". The keyword this doesn't exist in static methods. To call a static method, you don't even need an instance of that class (e.g. you can't create Math instances, but you can call Math.min() without any problem).
On the other hand, if you call an instance method, you need an instance of a class having that method, and this instance gets the name this inside the method. The method selection is done at runtime, based on the runtime class of the instance, no matter what the declared type is.
Java code:
class P {
public void hello() {}
}
class C extends P {
public void hello(String s) {}
}
My question is: Is the hello in class C overloading the one with same name in super class P?
My friend says they are not because the are not in the same class.
Taking a more formal approach, the Java Language Specification for Java 7 states:
If two methods of a class (whether both declared in the same class, or both inherited by a class, or one declared and one inherited) have the same name but signatures that are not override-equivalent, then the method name is said to be overloaded.
http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.4.9
I would point your friend to this link.
So, in short, in your example, the hello method is indeed overloaded.
Simple Explanation:
I think this question arises because at times we hear the following,
"Method overloading is performed within class.
Method overriding occurs in two classes that have inheritance relationship."
The above statement is correct. But your friend is wrong. why?
Because when you extend a class, the subclass have all the methods defined by superclass. It is as if all the methods of superclass have been implemented by the subclass. That means the hello() method has been implemented by the class C as well. Now, you added a method in class C with different parameter (hello(String s)). That means, class C has two methods in all with same name but different parameters and that is "overloading".
Hope it is crystal clear.
Overloading can happen in same class as well as parent-child class relationship whereas overriding happens only in an inheritance relationship.
Yes, your friend is wrong because he thinks only of the concept of overriding.
But here hello(), and hello(String s) are different by there parameters so it's overloading not overriding.
Source of confusion: Your friend would be right if speaking about C++ not Java. In C++, function overloading can only occur between members of the same class. Whereas in Java, overloading can occur, in addition to that, across two classes with inheritance relationship.
Yes it is overloading, This overloading is happening in case of the class 'C' which is extending P and hence having two methods with the same name but different parameters leading to overloading of method hello() in Class C. However Class P is only able to access one of the methods which is present in its own definition.
Long story short, an instance of C will have both the hello() and the hello(String s) methods available. An instance of P will only have the hello method available.
This is indeed overloading, as you have two methods of the same name taking different parameters.
However, it is not overriding, because overriding is having a method declared in a subclass with the same name and same parameters as a method in a superclass.
E.g. if you had
class C extends P {
public void hello() {}
}
it would be overriding the hello() method declared in P. When invoking new C().hello() in that case, you would invoke the implementation of the hello() method declared in class C.
It is a valid question since usually, overloading is explained using two methods with the same name (but different parameters) in the same class.
I would argue that yes, the method hello in C is overloading P's hello method because of the "is a" relation.
The "is a" relation states that since C subclasses P, it is also an instance of P ("C is a P"). Hence C has 2 overloaded hello-methods.
Good question!!!In sub class if method name | parameter type | list is changed then sub class method will not be considered as overriding it is considered as overloading method
Example :
class A{
void m1(int a){}
}
class B extends A{
void m1(float f)
{}
}
In above program m1 method is a overloaded method.
Yes we can overload the super class method in sub class like as bellow:
public class OverLoading {
public static void main(String[] args) {
B b = new B();
b.display();
b.display(4);
}
}
class A {
public void display() {
System.out.println("A class display method");
}
}
class B extends A {
public void display() {
System.out.println("class B subclass");
}
public void display(int a) { //Overloading in subclass
System.out.println("class B subclass with overloading");
}
}
Output:
class B subclass
class B subclass with overloading
Depends on the class. From class P's perspective (if the reference is P, the object can be of C) it is not. If you write something like: P p = new C(); there is no overloading because you cannot call p.hello("foo").
From class C's perspective it is overloaded because if you write C c = new C(); it has two methods with same name and different signatures.
This is a good question and the answer is a bit tricky.
Well, it's true that you can overload an inherited method from a parent class into a subclass. However, and here's the interesting part, the actual behavior depends on the reference variable type.
Let's consider the following example:
public class OverLoadingTest {
public static void main(String[] args) {
ChildClass cc = new ChildClass();
SuperClass sc = cc;
sc.method("lol");
cc.method("lol");
}
static class SuperClass {
public void method(Object o) {
System.out.println("SuperClass called.");
}
}
static class ChildClass extends SuperClass {
public void method(String s) {
System.out.println("ChildClass called.");
}
}
}
So, we have a class extending another and with a method that overloads a method from the parent.
It's easy to guess that if you have an instance of ChildClass, the two methods are overloaded, and overloading resolution takes place as it normally does.
However, let's consider creating an instance of ChildClass and assigning it to a reference variable of type SuperClass. Is the overloading thing still standing?
If you execute this program you will get this outptut:
SuperClass called.
ChildClass called.
The output clearly indicates that there's no overloading here in this case. This however can be altered by overriding the original method.
static class ChildClass extends SuperClass {
public void method(String s) {
System.out.println("ChildClass called.");
}
public void method(Object o) {
System.out.println("ChildClass called.");
}
}
Now, if you run the program again, you get this output:
ChildClass called.
ChildClass called.
Explanation
Now, why is JVM behaving that way? Why can't it see the overloading method as we're using an instance of the child class?
This takes us to how does JVM call a method. The JVM sees that you're referring to the object with a reference of type SuperClass, so, it can only use the methods that are related to that type, with the only exception is overriden methods. And since method(String) isn't overriding, we have method(Object) of the parent, hence, it's the one chosen for execution.
We then override the method to break this rule, and this is how the JVM called ChildClass.method(Object) even if the reference variable is of a parent class.
Overloading is when you have two methods that have the same name but different signatures (Your case).
Side note: Overriding is when you have two methods that have exactly the same signature and name and the parent class.
As shown in http://docs.oracle.com/javase/tutorial/java/IandI/override.html, Java does allow
Overriding an instance method by an instance method and
Hiding a static method by a static method
My question is why Java doesn't allow hiding a static superclass method by an instance method. This could be done like this:
class Base {
static void foo () {}
}
class Derived extends Base {
void foo () {}
void access () {
foo ();
Base.foo ();
}
}
I don't see any particular issue with the above approach - it is only as "messy/complex" as the (allowed) hiding of statics already is.
I suspect it is to avoid confusion with dealing with the base class. In fact I imagine the designers didn't see an obvious way this should behave.
class Base {
static void foo () {}
}
class Derived extends Base {
void foo () {} // say this compiled
}
Base b = new Derived()
b.foo(); // should the static or the virtual method be called?
Should b.foo() call Base.foo() or should it potentially call Derived.foo()?
Simple answer: that would be the mess.
Concrete answer: what to call in that case Derived.foo()? Base.foo() can't be called as it's hidden (as per you), Derived.foo() can't be called as it's not static.
Because, one are like Bananas and the other ones are Apples.
Explaination:
Static Methods are created when reading the Class-Structure
Methods are created when a object of a class is created.
Example:
Foo.bar();
is something different than
new Foo().bar();
Guess which one is called?
Foo f = new Foo();
f.bar();
Another to add here is:
1. Static methods belong at the class level. So u cannot override method in the derived class.
as simple its called hiding. :)
2. Instance methods belong to the objects, so objects are overrided. So we can override in the derived class.
Above other comments give a good example have a look into it..
Regards
Punith
I have the following classes.
public class Super{
public static void useSubClass(){
//I want to access the sub class object here, how.
}
}
public class Sub1 extends Super{
}
public class Sub2 extends Super{
}
I want to access the sub-class object from a static method in super-class. i.e. When I call Sub1.useSubClass() the method has access to Sub1.class and when I use Sub2.useSubClass(), I can access the Sub2.class.
Is there any way to access the sub-class object from super-class.
In general, you cannot do that from a superclass (and shouldn't!) because you won't know (and shouldn't assume anything about!) what classes will inherit from your superclass.
Depending on exactly what you want to do, there are alternatives, such as:
Use the template pattern to define "filler methods" that your subclasses must implement; these filler methods will be called by the template method in your superclass.
Define methods to be overridden by your subclass.
Define interfaces to be implemented by your subclass.
Update: As #JB Nizet has pointed out, I might have misread the question.
Here's something (very similar to the Observer Pattern) you can do if you wish to access subclasses from the static method in your superclass:
Define a static listener list in your superclass, call it List observerList
In the constructor of your superclass, add the class instance itself to that static observerList
For all subclasses, it is their responsibility to call super() from their constructors in order to register themselves to observerList (and unregister in deconstructor)
Then in your superclass's static useSubClass() method, you can iterate through that list of subclass instances, find the particular one you care about (maybe specified by some argument), and then do something with it.
Static methods are not inherited, and calling Sub2.useSubClass() is strictly equivalent to calling Super.useSubclass().
There is no way to get this information, because it doesn't exist. The compiler allows calling Sub2.useSubclass(), but translates it into Super.useSubclass().
public static void useSubClass(Super sub) {
if (sub instanceof Sub1) {
// Do something
} else if (sub instanceof Sub2) {
// Do something else
} else {
// Something else is extending Super
}
}
However, a better question is why? Can't you simply override the method in your subclass?
No you cannot because the super-class cannot know the methods of the sub-classes.
You should consider to create a new class which sees both super-class and sub-classes and implement the static method inside this new class
For the record, you could do this in Python, using class methods:
class super(object):
#classmethod
def usesubclass(cls):
print cls
class sub1(super):
pass
class sub2(super):
pass
Using this code, you could call sub1.usesubclass() or sub2.usesubclass(), and that would print the representations of the sub1 and sub2 classes, respectively:
>>> sub1.usesubclass()
<class '__main__.sub1'>
>>> sub2.usesubclass()
<class '__main__.sub2'>
Java, however, does not support such mechanisms, unfortunately. When you compile Sub1.useSubClass() in your example, the compiler will simply use Sub1 as the basic namespace to look up the the useSubClass() method in Super, but no information on that is actually compiled into code. In the resulting bytecode, the call is simply one directly to Super.useSubClass() and nothing more.
I sympathize with your plight, but Java is what it is. The closest thing you could come, I think, would be the following code:
public class Super {
public static <T extends Super> void useSubClass(Class<T> sub) {
}
}
And then call that method explicitly as either Super.useSubClass(Sub1.class) or Super.useSubClass(Sub2.class).
I figured something out. It works if implemented with care.
/** SuperClass.java **/
public abstract class SuperClass {
public static void printClass(){
System.out.println(new ImplementingClassRetriever().getCallingClass());
}
static class ImplementingClassRetriever extends SecurityManager{
public Class getCallingClass() {
Class[] classes = getClassContext();
for (Class clazz : classes) {
if (SuperClass.class.isAssignableFrom(clazz) && clazz != null
&& !clazz.equals(SuperClass.class)) {
return clazz;
}
}
return null;
}
}
}
/** Main.java **/
public class Main{
public static void main(String[] args) {
Sub.printClass(); //this does not work
Sub.testStaticCall(); //this works!! :)
}
}
class Sub extends SuperClass{
public static void testStaticCall(){
Sub.printClass(); //calling the method in the super class
}
}
This is just a toy example. The super class contains a static class that contains a method to retrieve the calling class.
In the subclass I have another static method which calls the superclass's method for printing the class name.
The Main class/function contains two calls to Sub's inherited and locally implemented method. The first call prints null, because the calling context (i.e. Main) is not a subclass of Super However the delegate method in Sub works because the calling context is now a subclass of SuperClass and hence the calling class can be determined.
Although You can create a reference to the super class and point it to any sub-class. This can also be done dynamically during run-time. This is a way of run-time polymorphism.