Why this in OOP - java

class Parent {
private int var = 1;
public int getVar() {
return var;
}
public void setVar(int var) {
this.var = var;
}
}
class Child extends Parent {
private int var = 2;
public int getVar() {
return var;
}
public void setVar(int var) {
this.var = var;
}
}
And now, when testing it, we get 2.
Child child = new Child();
Parent parent = (Parent)child;
System.out.println(parent.getVar());
I am casting the child object to a Parent explicitly and making my intentions clear
why then when i do parent.getVar() i get 2 ?

Child child = new Child();
Parent parent = (Parent)child;
You are simply using a super class reference to point. Your object is still of class Child and that will never change. So you would always get 2.
So when you call
System.out.println(parent.getVar());
at compile time it checks whether getVar() is present in class of reference Parent which is true. So it compiles. At runtime it knows the class of actual object which is Child and executes corresponding method.

Your object is Child here. But you are using Parent super class reference. At runtime, the object is of type Child, hence your code calling the child method results in getting 2.

The child getVar has overwritten the parent getVar method so even though your reference is typed as the parent, it's still the child and so still returns 2.
Having a known reference to the Child class you could have a special method on the child to access the parent var:
class Child extends Parent {
...
public int getParentVar() {
return super.getVar();
}
}

All methods in Java are virtual. That means that the reference type does not matter, what matters is the object type. You clearly have a reference to Child object, this is why Child's getVar() method is being executed.
What is even more fun to realize, that you have two different fields with name var, one in Parent and one in Child classes.

That's exactly the idea of OO: you can have different "childs" extending one parent with different implementations of methods (override) and in runtime the implementation that is called will be of the current object (polymorphism), regardless what you casted it to: during runtime the variables/class members will be read from the 'current' environment (the child in our case).
The use of such behavior (polymorphism) can be demonstrated with the following:
abstract class Shape {
abstract public double getArea();
}
class Square extends Shape {
double edge = 2.0;
public double getArea() {
return edge * edge;
}
}
class Circle extends Shape {
double radius = 2.0;
public double getArea() {
return Math.PI * radius * radius;
}
}
public class TestShapes {
public static void main(String[] args) {
Shape[] shapeArray = new Shape[2];
shapeArray[0] = new Square();
shapeArray[1] = new Circle();
for (Shape p: shapeArray) {
// every shape "knows" how to calculate its own area
// there's no need to find out which type of shape is it
// and there's no need to cast anything!
System.out.println("Area: " + p.getArea());
}
}
}
That said, if you want to call from the child to a parent-method (which is a bad practice!) you can do it using super keyword:
class Child extends Parent {
private int var = 2;
public int getVar() {
return super.getVar();
}
}
// usage:
Child c = new Child();
System.out.println(c.getVar()); // will print "1"

Related

child class object in unable to run overridden method instead parent class method is being run both times

new to programming...just trying to understand method overriding.
In the following code, object from child class which overrides Parents class method, but still with child class object I can't run overridden method (m()).
I set return type different-- float in parent and double in child, if the particular method is not overridden due to that then child class also implements the same method from interface u and still not running overridden method..
class Parent {
public float m(float m){
System.out.println(" parent class with float return");
return m;
}}
class Child extends Parent implements u {
#Override
public double m(double y) { /*method name same - Parent class & interface
different return type */
System.out.println(" child class with double");
return y;
}
public static void main(String[] args) {
Child child = new Child();
child.m(10);/*child object running parent method*/
Parent g = new Child();
g.m(10);
}
}
interface u {double m(double y);}
You are trying to override a method called m which returns a double which doesn't exist in the parent class, the parent class has a method m with a return type of float, these are different. Basically the current #Override doesn't actually override anything since a method with that name and return type doesn't exist in the parent.
You fulfil the interface contract because a method m exists which returns a double.
The reason why you get the same output is because you are calling the Parent classes m function because of the type of argument you are passing in (10 is being determined as a float). If instead you call the function with a double, i.e 10d then the Child classes m method will be called.
Change your main method to the following and it will now call the parent and child methods:
public static void main(String[] args) {
Child child = new Child();
child.m(10.0);/*child object running parent method*/
Parent g = new Child();
g.m(10);
}

Use child's attribute in parent's constructor

class abstract Parent ()
{
private int a;
private final int b = a + 1; // a is null at that point
}
class Child extends Parent
{
public Child()
{
a = 2;
}
}
That wouldn't really be a problem in C++ (because pointers), but I'm not sure how to handle this issue in Java. Obviously a is equal to 0 when Parent tries to initiate b.
I initially tried calling super() after setting a, but apparently super() has to be called first in child's constructor. I don't want to set b in Childs and I'd prefer b to be final too. Any ideas?
What you want cannot be done like this, what you need to do is pass the value of a to a constructor of Parent:
abstract class Parent {
private int a;
private final int b;
protected Parent(int a) {
this.a = a;
b = a + 1;
}
}
And define Child as:
class Child extends Parent {
public Child() {
super(2);
}
}

This keyword referring to a parent variable

Today a fellow learner came up with an interesting query. We know that this keyword is used to refer to the current object. But I could not explain to him how this keyword behaves as seen in the following snippet. I know what inheritance is: allows access to parent class variables and methods. But are they copied into the memory area of child instance?, because I am able to use this keyword to access the parent class property.
I was able to refer to parent class variable. I searched and found that nothing gets copied virtually to child class, but why the following behavior happens? Please explain this case of using this.
class Parent {
int a=10;
}
public class Child extends Parent{
void m1(){
System.out.println(a);
System.out.println(this.a);
System.out.println(super.a);
}
public static void main(String[] args){
new Child().m1();
}
}
https://docs.oracle.com/javase/tutorial/java/javaOO/thiskey.html
https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
The property a is inherited by Child. Therefore, you can use this.a in child to reference it.
Where was the problem supposed to be?
I searched and found that nothing gets copied virtually to child class
You have the wrong example to illustrate that statement.
The way to understand that is (roughly): "instance variables are not overridden when re-declared in subclasses, so you can't declare an instance as Parent and expect to get Child.a if the instance was created with new Child()". Here's an example of the problematic case:
class Parent {
int a = 10;
}
public class Child extends Parent{
int a = 12; //not overridden
public static void main(String[] args){
Parent child = new Child();
System.out.println(child.a); //This will print 10, not 12
}
}
System.out.println(child.a); will print 10 because variables instance fields don't get overridden. You get the value based on the declared type (Parent in this case)
When you instantiate a class Child it contains all members of itself and of Parent. However, private members of Parent are not accessible from Child:
class Parent {
private int p = 10;
}
public class Child extends Parent{
void m1(){
System.out.println(p); // compilation error
}
}
Another interesting case is when one instance of Parent tries to access a private field of another instance of Parent. What do you think happens?
public class Parent {
private int p = 11;
public boolean same(Parent other) {
return other.p == p;
}
}
You might think other.p will result in a compilation error since p is a private field. However, since privacy does not pertain to object instances, but to classes. So all private fields in Parent are visible within all Parent instances, so this works!
Consider below Code:
this is a reference variable which will point to the current object.
super is used to refer to Parent's property in case you have created
the same in the child.
class Product{
String color;
public Product() {
color = "Black";
}
}
class Mobile extends Product{
String color;
Mobile(){
color = "White";
}
void showMobileData(){
System.out.println("this hashCode is "+this.hashCode());
System.out.println("super hashCode is: "+super.hashCode());
System.out.println("color is: "+color);
System.out.println("this.color is: "+this.color);
System.out.println("super.color is: "+super.color);
}
}
public class Test {
public static void main(String[] args) {
//new Mobile().showMobileData();
Mobile mRef = new Mobile();
System.out.println("mRef HashCode: "+mRef.hashCode());
mRef.showMobileData();
}
}

Can a parent class call the method of a grandchild class?

I have a main method in my overall parent class, outside of that main method I have two other methods that I will call inside the main method. Each of these outside methods call a method that was defined in, not the child, but the grandchild class.
Here is where I get really confused. In my big parent class, the two methods that aren't the main method take in an array that is the type of the child class. This is because each item in the array is a different type the grandchild classes. I get that because the methods that I'm calling in the parent class aren't defined in the child class (they are defined in the grandchild class) that is why they cannot be called. Is there a way to typecast the indexes to each individual grandchild class type in a for loop in the array? Or any other way?
Sorry if this is a super confusing way to phrase this question.
The normal way to do this is for the parent class to be declared abstract, and to declare that the method should exist. The grandchild class will supply a version of the method. For example:
public abstract class Doubler {
int a;
public Doubler(int a) {
this.a = a;
}
abstract int modifyResult(int aResult);
int calculate() {
int rv = a * 2;
return modifyResult(rv);
}
}
public class DoublerAndAdder extends Doubler {
int b;
public DoublerAndAdder(int a, int b) {
super(a);
this.b = b;
}
#Override
public int modifyResult(int aResult) {
return aResult + b;
}
}
calculate() is allowed to call modifyResult() even though modifyResult() is declared abstract and there is no implementation. Calling DoublerAndAdder.calculate() will run Doubler.calculate(), which will call DoublerAndAdder.modifyResult().
If you can't make the parent class abstract, the parent class can provide a version of the method which doesn't do anything:
public abstract class Doubler {
int a;
public Doubler(int a) {
this.a = a;
}
public int modifyResult(int aResult) {
return aResult;
}
int calculate() {
int rv = a * 2;
return modifyResult(rv);
}
}

Java Extends not updating

I am currently working on a hibernate project(EJB and JSF), and i have multiple java classes. The data of parent is being change in the front end with JSF, however, it is not updating in the child class. I need to access the data in the child class to do some calculation. Any Ideas as to how to pass the value of a variable from a parent class to a child class?
Thanks in advance
Example:
Parent class
public class parent {
private String x = "a+";
public String getx(){
return x;
}
public void setx(String x){
this.x = x;
}
}
child class
public class child extends parent{
private String z;
public String getZ(){
System.out.print(getx());
return z;
}
}
main class
public static void main(String[] args) {
parent p = new parent();
System.out.println("Original" + p.getx());
p.setx("z");
System.out.println(" Add z" +p.getx());
child c = new child();
System.out.println("child getx" +c.getx());
p.setx("zZ");
System.out.println("child getz" +c.getZ());
}
}
result.
Original a+
Add z z
child getx a+
a+child getz null
I don't understand what you expect here. Everything is working fine.
In your example, you never call c.setX, so why would you expect it to print anything other than a+? p refers to a completely different object, and has no relation to c. Therefore, calling p.setx will have no effect on c. If you want to set c.x, just call c.setx("z"). Do to polymorphism, since child extends parent, you can call methods declared in parent on an instance of child.
You are setting 'z' on two different objects, c and p. In order for 'c.getZ() to return zZ, you would need to call c.setx("zZ").

Categories