inheritance of class in java - java

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

Related

How to solve this method override and polymorphism problem that have different scope?

What will be the result of attempting to compile and run the following program?
public class Main {
public static void main(String[] args) {
A ref1 = new C();
B ref2 = (B) ref1;
System.out.println(ref2.g());
}
}
class A {
private int f(){
return 0;
}
public int g(){
return 3;
}
}
class B extends A{
private int f(){
return 1;
}
public int g(){
return f();
}
}
class C extends B{
public int f(){
return 2;
}
}
I tried it and got the answer 1, but I didn't know why.
I modified the following code:
public class Main {
public static void main(String[] args) {
A ref1 = new C();
B ref2 = (B) ref1;
System.out.println(ref2.g());
}
}
to
public class Main {
public static void main(String[] args) {
A ref1 = new C();
System.out.println(ref1.g());
B ref2 = (B) ref1;
System.out.println(ref2.g());
}
}
Its output is
1
1
I can't understand why both ref1 and ref2 are 1 regardless of whether the type is cast to B.
However, if I remove both public and private, like this
public class Main {
public static void main(String[] args) {
A ref1 = new C();
B ref2 = (B) ref1;
System.out.println(ref2.g());
}
}
class A {
int f(){
return 0;
}
int g(){
return 3;
}
}
class B extends A{
int f(){
return 1;
}
int g(){
return f();
}
}
class C extends B{
int f(){
return 2;
}
}
The output becomes 2.
I wonder if this has something to do with private and public too?
My understanding is:
ref1 is of class A and refers to class C.
The superclass of C is B.
The f() method in class B is private, that is, the subclass is "hiding", so it has not been "copied" to the subclass C, so it seems to be overriding, but it is actually a new method belonging to the subclass C, but it "just happens" to have the same name as the method in the parent class.
Moreover, there is no g() in class C, so g() in B is used, and the return is f() in class B.
So the result is 1.
However, if the private and public are removed, then C can override the
f() method in B, and at this time g() will be linked to the f() method of C.
Is my understanding correct?
Thank you very much.

What does makes those methods calls returns those values?

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 procedures of extending abstract class

I am not clear about the procedure of extending a class. Given the following piece of code, why the output is 32?
class Rts {
public static void main(String[] args) {
System.out.println(zorg(new RtsC()));
}
static int zorg(RtsA x) {
return x.f()*10 + x.a;
}
}
abstract class RtsA {
int a = 2;
int f() { return a; }
}
class RtsB extends RtsA {
int a = 3;
int f() { return a; }
}
class RtsC extends RtsB {
int a = 4;
}
First off, fields aren't overridden, so all this is equivalent to
public class Rts {
public static void main(String[] args) {
System.out.println(zorg(new RtsC()));
}
static int zorg(RtsA x) {
return x.f()*10 + x.a;
}
}
abstract class RtsA {
int a = 2;
int f() { return a; }
}
class RtsB extends RtsA {
int b = 3;
int f() { return b; }
}
class RtsC extends RtsB {
int c = 4;
}
The implementation of f() for an object of type RtsC comes from RtsB, since that is the lowest-level class that overrides f(), so its implementation is used, and that returns b, which is 3. That's multiplied by 10, and then added to the a from RtsA, since zorg only knows that x is of type RtsA, so that field is used. That's 3 * 10 + 2 = 32.
(Note that the fact that RtsA is abstract didn't come into this at all; that mostly only matters when you have abstract methods to worry about.)

Calling an overridden superclass method from a subclass

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
}

Java : Using parent class method to access child class variable

I have the following scenario :
public class A {
private int x = 5;
public void print()
{
System.out.println(x);
}
}
public class B extends A {
private int x = 10;
/*public void print()
{
System.out.println(x);
}*/
public static void main(String[] args) {
B b = new B();
b.print();
}
}
On executing the code, the output is : 5.
How to access the child class(B's) variable(x) via the parent class method?
Could this be done without overriding the print() method (i.e. uncommenting it in B)?
[This is important because on overriding we will have to rewrite the whole code for the print() method again]
EDITED
More Clarification :-
The motive of the question is to use the value of a child class private variable from its parent class method. This doesn't require changing the value of the parent class private variable in order to achieve the desired result.
The answers posted here, though, led me to my desired answer, which I have posted below.
(Thanks all for your time and help )
class A {
private int x = 5;
protected int getX() {
return x;
}
protected void setX(int x) {
this.x = x;
}
public void print() {
// getX() is used such that
// subclass overriding getX() can be reflected in print();
System.out.println(getX());
}
}
class B extends A {
public B() {
// setX(10); // perhaps set the X to 10 in constructor or in main
}
public static void main(String[] args) {
B b = new B();
b.setX(10);
b.print();
}
}
EDITED
Below is a general answer using abstract class and method to solve similar scenario:
abstract class SuperA {
protected abstract Object getObj();
public void print() {
System.out.println(getObj());
}
}
class A extends SuperA {
#Override
protected Object getObj() {
// Your implementation
return null; // return what you want
}
}
class B extends A {
#Override
protected Object getObj() {
// Your implementation
return null; // return what you want
}
public static void main(String[] args) {
B b = new B();
b.print();
}
}
After reading all the answers posted here, I got what I was looking for. The following is what I feel is the best answer for my question :
public class A {
private int x = 5;
protected int getX(){
return x;
}
public void print(){
System.out.println(getX());
}
}
public class B extends A {
private int x = 10;
protected int getX(){
return x;
}
public static void main(String[] args) {
B b = new B();
b.print();
}
}
Setting up a protected getter and overriding it is better than overriding the print() method itself, as there could be any other huge method in place of the print method which might need to access the value of the child class variable(s).
To solve your question you have to define the fields in the parent class A like protected (so it will be inherited on the child class) and set the field value x inside the constructor in the child class B. The print method is also inherited from A class so you can invoke it directly from parent class.
I hope this can help you.
public class A
{
// fields declaration
protected int x = 5;
public void print()
{
System.out.println(x);
}
}
public class B extends A
{
public B()
{
// set child x value. The field have been defined in the parent class
x = 10;
}
public static void main(String[] args)
{
A a = new A();
a.print(); // print 5
B b = new B();
b.print(); // print 10
}
}
You can always add it to the constructor:
public class B extends A {
//this line is unnecessary: private int x = 10;
/*public void print()
{
System.out.println(x);
}*/
public B()
{
x=10;
}
public static void main(String[] args) {
B b = new B();
b.print();
}
}
The reason it won't work as you try it is that default values only get evaluated once. So when it's default 5 in A, it stays 5 even though you used default 10 in B.
You should expose a getter for the value you want and override that in the child class.
Like so:
public class A {
private int x = 5;
public void print()
{
System.out.println(getX());
}
protected void setX(int x)
{
this.x = x;
}
protected int getX()
{
return x;
}
}
public class B extends A {
/*public void print()
{
System.out.println(x);
}*/
public B()
{
setX(10);
}
public static void main(String[] args) {
B b = new B();
b.print();
}
}

Categories

Resources