This question already has answers here:
Are static methods inherited in Java?
(15 answers)
Closed 9 years ago.
In Java, "this" refers to the current object. I assumed that "this" is the same type as the current object, but consider this example:
class A {
static void f() {
System.out.println("A.f");
}
void g() {
this.f();
}
}
class B extends A {
static void f() {
System.out.println("B.f");
}
}
public class C {
public static void main(String[] args) {
B test = new B();
h(test);
}
static void h(B x) {
x.g();
}
}
The result is:
A.f.
Which I don't understand, because when x.g() is called, x is of type B. In the x.g() call, g is looked up in B, then in A (because B subclasses A). g then calls f, an instance method of both A and B, meaning that the version of f called depends on the type of the implicit THIS parameter. I would assume that B.f() would be called since X is of type B, but this is not so.
What type does THIS take on, exactly?
static methods are not inherited. When you call
static void h(B x) {
x.g();
}
You are calling g() declared in class A which calls
static void f() {
System.out.println("A.f");
}
Methods are resolved on the static type of the reference they are called on. For instance methods, polymorphism and late-binding do their trick to execute the actual method. However, since late binding doesn't apply to static methods, you are calling A.f().
You can call static methods on instance references and they are resolved on their declared type. This is not recommended.
Related
This question already has answers here:
Vararg methods Override/Overload confusion
(3 answers)
Closed 4 months ago.
Could someone explain why while upcasting when we have varargs in parent class, the method of parent class executes instead-of child's one?
public class Test {
public static void main(String[] args) {
A a = new B();
a.foo("123");
}
}
class A {
public void foo(String... s) {
System.out.println("A");
}
}
class B extends A {
public void foo(String s) {
System.out.println("B");
}
}
Could someone explain how it works?
The type of a variable defines the interface you can use to interact with the object it's referring to. In this case, you are referring to a B instance through a variable of type A. Because A has only the varargs version of foo(), only this one is available for the compiler to choose.
This question already has answers here:
Calling non-static method from another non-static method
(2 answers)
Calling non static method without class instance inside a non static method
(2 answers)
Closed 1 year ago.
Why is it possible to use a non-static method inside the class it's been created without an object but impossible to do inside the Main method if it's also inside the class for example :
public class C {
public void f() {...};
public void g() { f() }; //no error
public static void Main(String[] args) {
f(); //compilation error.
}
}
Inside an instance of a class, there is an implicit this when invoking methods in it.
public class C {
public void f() { }
public void g() {
this.f(); // not a compile-time error; this refers to an instance of C
}
}
Inside a static method, there is no this because static methods have no instance attached to them, thus it would be a compile-time error to try to refer to it.
From the JLS:
A class method is always invoked without reference to a particular object. It is a compile-time error to attempt to reference the current object using the keyword this (§15.8.3) or the keyword super (§15.11.2).
So in the static method, you need an instance of C to invoke f.
public static void main(String[] args) {
new C().f();
}
This question already has answers here:
Polymorphism and Constructors
(2 answers)
Closed 3 years ago.
I have a derived Java class override a base class' method. When the base class calls the method, it executes the derived class' function, rather than its own. Why?
public class HelloWorld{
public static void main(String []args){
Derived d = new Derived();
System.out.println("Main");
}
}
class Base {
void f() {
System.out.println("Base::f()");
}
public Base() {
f();
}
}
class Derived extends Base {
void f() {
System.out.println("Derived::f()");
}
public Derived() {
f();
}
}
The code prints Derived::f() twice, I expect it to print Base::f() followed by Derived::f(), as would happen in C++
In Java, unlike in C++, instance methods are virtual by default. It means that a method call is dispatched at the run time according to the actual run-time class of an object (not at the compile time). In C++, you achieve this behaviour with keyword virtual.
Your Derived f() method is overriding the Base f() method. If you want to see the Base method try putting super.f(); in the start of the Derived f() method, this will call the super class' f() method.
This question already has answers here:
Are static methods inherited in Java?
(15 answers)
Why doesn't Java allow overriding of static methods?
(22 answers)
Closed 6 years ago.
Suppose I have the following simple code:
class A {
protected int someMethod() {
return staticMethod();
}
private static int staticMethod() {
return 10;
}
}
class B extends A {
protected int someMethod() {
return super.someMethod();
}
public static int staticMethod() {
return 20;
}
}
class TestX {
private void main() {
B b = new B();
int finalValue =b.someMethod();
}
}
In the above code, when b.someMethod() is executed, it ends up calling A's version of staticMethod(). But I thought static methods are called based on the type of reference of the main object. Since the object on which someMethod() is called is of type B, shouldn't B's version of staticMethod() be called even when A's someMethod() is called (because of the line return super.someMethod();) ?
Given the above code, is there a way I can make B's staticMethod() get executed so that 20 is returned instead of 10 ?
I found a similar question but the idea suggested in it isn't relevant to me I think:
Calling subclass's static method from parent class
This question already has answers here:
Private methods in Inheritance
(9 answers)
Closed 7 years ago.
A friend of mine asked this question to me. Why the following code does not give error on invoking aa.x()?
I understand that aa is a reference to object of class B but is invoking private method of class A inside the method of class A where it is visible and hence accessible.
Is my understanding correct? Or is there any other reason behind this?
public class A {
public void xyz() {
System.out.println("A");
}
private void x() {
System.out.println("A:x");
}
public static void main(String[] args) {
B b = new B();
A aa = b;
aa.x();
aa.xyz();
B bb = (B) aa;
bb.xyz();
bb.xyz12();
}
}
class B extends A {
public void xyz() {
System.out.println("B");
}
public void xyz12() {
System.out.println("B-12");
}
}
I can't immediately find a duplicate using a subclass, but fundamentally it's the same answer as the answer to this question.
There are two things that govern access to x:
Where the code is that's doing the access. Since x is private to A, the code accessing it must be part of a method in A. It can't be in a subclass (B) or an unrelated class.
What kind of reference you're using. If you have an A reference, you can access x on it. If you have a B reference, you can't, even though your code is part of an A method. You could cast it to A and then access x, but you can't do it directly with a reference of type B.
It is only visible because the main method where it is invoked is contained in class A. Move it to class B and it will not work
As the private methods are not inherited, a superclass reference calls its own private method.
Your main method is the method of A, therefore it can can call x() private method.
private modifier—the field is accessible only within its own class.