What is the value of a.x?
I think dynamic binding choses the g() function in the superclass because super.f() is called. Or am I wrong and does dynamic binding call the override function of g() so the result becomes 27? If so, why?
I've modified your code to trace what's going on:
public class A {
public void f() { System.out.println("A.f");x = x + 4; g();System.out.println(this); }
public void g() { System.out.println("A.g");x = x + 10;}
public int x = 5;
}
public class B extends A {
#Override public void f() { System.out.println("B.f");x = x + 3; super.f(); }
#Override public void g() { System.out.println("B.g");x = x + 15; }
}
The output is:
B.f
A.f
B.g
com.sandbox.Main$B#18fb53f6
27
When g() is called from A, you can see this is actually a B object, that's why the g() method from B is invoked.
All instance methods in java are virtual, so B.g() is called and the answer is 27.
Related
I need to write what is the output of those methods calls.
My answer was:
I i = new A();
i.m(b);
My answer: m_IB because I doesn't have any method with a B type so I went down to class A which implements I. A doesn't also have any methods with parameter B but it extends I.IImpl which has a method with m(B b) that prints m_IB.
I j = new B();
j.m(b);
My answer: m_BB becuase again I doesn't have any method with a B type so I went down to class B because I j = new B() and it has a m(B b) which print m_BB.
interface I {
public void m(A a);
class IImpl {
public static void m(B b) { System.out.println("m_IB"); }
}
}
class A extends I.IImpl implements I {
public void m(A a) { System.out.println("m_AA"); }
}
class B extends A {
public void m(A a) {
super.m(a);
System.out.println("m_BA");
}
public static void m(B b) { System.out.println("m_BB"); }
}
public class Interfac {
public static void main(String[] args) {
A a = new A();
B b = new B();
a.m(b); System.out.println(); // m_IB
I i = new A();
i.m(b); System.out.println(); // m_AA
I j = new B();j.m(b); // m_AA m_BA
}
}
Both of my answers are wrong and the correct output is m_AA for i and m_AA m_BA for j.
I can't understand why I get this output even if I'm calling a method with a type B.
Both of the correct answer are calling a m(A a) methods.
Your interface provides this method:
public void m(A a);
And your j is declared like this:
I j = new B();
So, yes, it's an instance of B, but it is declared as an I, meaning, when you call that method, it calls the method provided by the interface, not the overloaded one.
So, in class B it takes the method that is provided by the interface:
public void m(A a) { // this one
super.m(a);
System.out.println("m_BA");
}
// not this overloaded one
public static void m(B b) { System.out.println("m_BB"); }
The first line of that method is:
super.m(a);
Which calls the m(a) method in the A class, which then prints: "m_AA".
Then, it prints "m_BA"
Java 8
I was just a little perplexed by that we could not call virtual method from a constructor. The pitfall is that we can overload it and crash. But what if we call it from within a constructor of a final class. Like this:
public final class MyClass implements MyInterface {
private final Object[] arr;
public MyClass(){
Object[] arr;
//init arr
this.arr = arr;
//Now we have to preprocess it
preprocess();
}
#Override
public void preprocess(){
//impl
}
public int count(){
//impl
}
}
public interface MyInterface{
void preprocess();
int count();
}
Are there other pitfalls with calling virtual methods from within a constructor? Of course, I can extract preprocess into a static method and then call it from both, but it looks a little messy. I'd like to keep code as clean as possible.
You should always take care when calling methods from a constructor, because the object construction is not yet complete. This is true even for final and private methods, which cannot be overridden by subclasses.
Example:
public class Test {
public static void main(String[] args) {
new Sub().test();
}
}
class Base {
int b;
Base() {
test();
this.b = 1;
}
void test() {
System.out.println("Hello from Base. b = " + this.b);
}
}
class Sub extends Base {
int s;
Sub() {
test();
this.s = 2;
}
#Override
void test() {
System.out.println("Hello from Sub. b = " + this.b + ", s = " + this.s);
}
}
OUTPUT
Hello from Sub. b = 0, s = 0
Hello from Sub. b = 1, s = 0
Hello from Sub. b = 1, s = 2
test() is called 3 times: From Base constructor, from Sub constructor, and from main().
As you can see, even field b was not yet initialized on the first call.
So, is it illegal to do it? No.
Should you avoid it? Yes.
Just make it clear (e.g. javadoc) that the method may be called on partially initialized objects.
I have output for this program that I don't understand how does it happens
here is the output
i from A is 40
i from A is 60
i from B is 60
I do understand the first line of output but nothing after that. Does this have to do with polymorphism ?
public class Test {
public static void main(String[] args) {
new A();
new B();
}
}
class A {
int i = 7;
public A() {
setI(20);
System.out.println("i from A is " + i);
}
public void setI(int i) {
this.i = 2 * i;
}
}
class B extends A {
public B() {
System.out.println("i from B is " + i);
}
public void setI(int i) {
this.i = 3 * i;
}
}
Yes. B extends A meaning it is a subclass of A.
Thus it shares i which is initialized only in A and then shared in B.
So B starts with what?
An i with "initial" value equal to 20.
It is java functionality
Whenever you create a child class object default constructor/argument-less constructor implicitly gets called.
And in your case first call is to A() constructor and then B() constuctor, and method call get to local method of B class
`ie public void setI(int i) {
this.i = 3 * i;
}
If you want to avoid this you can do this by making a call to super class constructor explicitly.
For example:
public class Test {
public static void main(String[] args) {
// new A();
new B();
}
}
class A {
int i = 7;
public A() {
setI(20);
System.out.println("i from A is " + i);
}
public A(int x)
{
System.out.println("This is a super call");
}
public void setI(int i) {
this.i = 2 * i;
}
}
class B extends A {
public B() {
super(10);
System.out.println("i from B is " + i);
}
public void setI(int i) {
this.i = 3 * i;
}
}
Output will be :
This is a super call
i from B is 7
public class F {
protected int a=0, b=0;
public F() {
a = 2;
b = 2;
}
public void increase() {
upA();
}
public void upA() {
a = a + 1;
}
public String toString() {
return a+" "+b;
}
}
public class G extends F {
public void increase() {
super.increase();
upB();
}
public void upA() {
a = a + a;
}
public void upB() {
b = b + 1;
}
}
What is printed in the Output window by the following Java fragment?
G g = new G();
g.increase();
System.out.println(g);
Can someone explain to me why the answer is 4,3
(ie. the subclass method is called even though I have called super.increase() which calls the upA method in the superclass?)
All your methods are being called virtually, with overrides applying. So this code in F:
public void increase() {
upA();
}
... is invoking G.upA(), because the object it's calling upA() on is an instance of G.
So the execution flow for increase() is:
G.increase() calls super.increase()
F.increase() calls upA()
G.upA() executes (so a = 4)
G.increase() calls upB()
G.upB() executes (so b = 3)
Think of increase() as being implemented like this
public void increase() {
this.upA();
}
and then ask yourself what object "this" is.
You are seeing "polymorphic" behaviour, and it's a really powerful feature of Object languages.
Note that you can write
F gInDisguiseAsAnF = new G();
gInDisguiseAsAnF.increase();
and still get the same result. Which version of the upA() method is selected on the basis of the type that was newed.
public void increase() {
upA();
}
is same as this.upA(), so the method in G was called, since this is instance of G.
calling super won't restrict your current instance only in super type.
This is being called from increase() of F
public void upA() {
a = a + a; // a=2+2
}
Not,
public void upA() {
a = a + 1; //not a=2+1
}
Consider the following code in Python:
class A(object):
CLASS_ATTRIBUTE = 42
def f(self):
return "CLASS_ATTRIBUTE: %d" % self.CLASS_ATTRIBUTE
class B(A):
CLASS_ATTRIBUTE = 44
Now A().f() and B().f() return "CLASS_ATTRIBUTE: 42" and "CLASS_ATTRIBUTE: 44" respectively.
How can I achieve a similar effect in Java? I want a CLASS_ATTRIBUTE field to be initialized statically and redefined in the inherited class but the f method should be only defined in the base class.
Is there a particular reason you want the attribute to be static? In Java the typical way you'd do this is to have A contain a protected variable that you then set in the constructors of the 2 classes:
public class A
{
protected int CLASS_ATTRIBUTE;
public A()
{
CLASS_ATTRIBUTE = 42;
}
public String f()
{
return "CLASS_ATTRIBUTE: " + CLASS_ATTRIBUTE;
}
}
public class B extends A
{
public B()
{
CLASS_ATTRIBUTE = 44;
}
}
Alternatively (and probably more consistent with Java design patterns) you'd declare a function that you can override to return the value instead of using a member variable.
Short answer: you cant solve it like this in Java. You'll have to solve it in another way.
In Java you can't override or "redeclare" fields in subclasses, and you can't override static methods.
It can be solved using an ugly reflection-hack (should be avoided though):
public class Main {
public static void main(String... args) {
A a = new A();
B b = new B();
System.out.println(a.f()); // Prints 42.
System.out.println(a.fReflection()); // Prints 42.
System.out.println(b.f()); // Prints 42.
System.out.println(b.fReflection()); // Prints 44.
}
}
class A {
static int CLASS_ATTRIBUTE = 42;
public int f() {
return CLASS_ATTRIBUTE;
}
public int fReflection() {
try {
return getClass().getDeclaredField("CLASS_ATTRIBUTE").getInt(null);
} catch (Exception wontHappen) {
return -1;
}
}
}
class B extends A {
// Compiles, but will not "override" A.CLASS_ATTRIBUTE.
static int CLASS_ATTRIBUTE = 44;
}
You can't do this directly with only a variable, because in Java variables cannot override (they only shadow the super classes variables).
You need to use a protected "getter" method, which can then be overridden by the subclass:
class A
{
private int attribute=42;
...
protected int getAttribute() {
return attribute;
}
}
class B
extends A
{
private int attribute=44;
...
protected int getAttribute() {
return attribute;
}
}
But note there's a special consideration to calling methods from an object's constructor, in that it allows object code to run before object construction is complete.
I'm not sure if you meant "statically" literally or not, but here's a brief example of how inheritance at it's most basic form looks in Java. Note that using a getter method to access the variable is a better idea for several reasons -- this is just an example.
public class Dog {
protected String whatISay = "Woof!";
public void speak(){
System.out.println(whatISay);
}
}
public class Poodle extends Dog {
public Poodle(){
whatISay = "Yap!";
}
}
public class Main {
public static void main(String[] args){
Poodle fluffy = new Poodle();
fluffy.speak();
Dog dog = new Dog();
dog.speak();
}
}
Yap!
Woof!
This way of doing it introduces as little intrusion as I could think of. setAttribute() could be named something like setDefaultValue() if that's clearer.
public class A
{
protected int attribute;
public A()
{
setAttribute();
}
public String f()
{
return "CLASS_ATTRIBUTE: " + attribute;
}
protected void setAttribute()
{
attribute = 42;
}
}
public class B extends A
{
#Override
protected void setAttribute()
{
attribute = 44;
}
}
public class Main
{
public static void main(String[] args)
{
A a = new A();
B b = new B();
System.out.println("A: " + a.f());
System.out.println("B: " + b.f());
}
}