Use child's attribute in parent's constructor - java

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);
}
}

Related

why am i not able to change the value of an variable of the parent class using a constructor in the child class?

class Parent{
int a ;
Parent(){
}
public int getA() {
return a;
}
Parent(int c){
this.a=c;
System.out.println("I AM IN Parent AND THE VALUE OF a is : "+a);
}
}
class Child extends Parent{
Child(int c){
super(c);
System.out.println("I AM IN Child");
}
}
public class Super {
public static void main(String[] args) {
Parent one = new Parent();
Child two = new Child(32);
System.out.println(one.getA());
}
}
//Output
I AM IN A AND THE VALUE OF a is : 32
I AM IN B
0
I am not able to change the value of the variable a of the parent class using a constructor in the child class
the way you wrote the code, one is an instance of Parent and two is another instance of Parent, they are stored in different parts of memory and they are independent,
Parent one = new Parent();
Child two = new Child(32);
System.out.println(one.getA());
System.out.println(two.getA());
will output the following
I AM IN Parent AND THE VALUE OF a is : 32
I AM IN Child
0
32
which worked correctly.

Why this in OOP

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"

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);
}
}

private member accessible via public method

The private modifier specifies that the member can only be accessed in its own class. But am I able to access it using a public method that get inherited from base class. Can someone explain me why? Does this mean object of Child class contain a member called b?
Here's the code:
package a;
public class Base {
private int b;
public int getB() {
return b;
}
public void exposeB() {
System.out.println(getB());
}
public Base(int b) {
this.b = b;
}
}
package b;
public class Child extends Base {
Child(int b) {
super(b);
}
public static void main(String args[]) {
Child b = new Child(2);
// Prints 2
System.out.println("Accessing private base variable" + b.getB());
}
}
you are not accessing the private variable in your super class directly. you are implementing the concept of Encapsulation. you are using the public getter method(in this case getB()) to make your private data accesed by other classes. thus, you can access private variable b through public getter but you never cant access b directly on its instace from another/subclass
In class Base, the field b is private but getB() is public so anybody can call that method.
What you can expect to fail compilation is something like:
System.out.println( "Accessing private base variable" + b.b );
(unless that line is called from within a method of Base itself).
You will not be able to access b directly in Child because it is private. You can, however, use the base-class's getB method which is public (and hence can be called anywhere).
To allow only extending classes and other classes in your package to access the field, you can declare it as protected.
class A {
private int n;
public A(int n) { this.n = n; }
public int n() { return n; }
}
class B extends A {
public B(int n) { super(n); }
public void print() { System.out.println(n); } // oops! n is private
}
class A {
protected int n;
public A(int n) { this.n = n; }
public int n() { return n; }
}
class B extends A {
public B(int n) { super(n); }
public void print() { System.out.println(n); } // ok
}
The private modifier means that you can't reference that field outside the class. Because getB() is public, however, you can reference that method. The getB() method can reference the private b field, because it's inside the class, and therefore can access it.
Private variable means that you can't access directly the variable from its class.... Declaring that variable private means that you can't do this
Myclass.myprivatevariable = 3
This will throw a compile error complaining that myprivatevariable is not visible fro the outside
But, as you did.... Declaring an internal method as getter or setter, public, you are allowing the user, only just through that method, to access indirectly that variable... That is always the preferred way to do.

Java Inheritance Example

Below is the example for Inheritance
class Parent {
Parent(int a, int b) {
int c = a + b;
System.out.println("Sum=" + c);
}
void display() {
System.out.println("Return Statement");
}
}
class Child extends Parent {
Child(int a, int b) {
int c = a - b;
System.out.println("Difference=" + c);
}
}
public class InheritanceExample {
public static void main(String args[]) {
Child c = new Child(2, 1);
c.display();
}
}
I get the below error when I don't have the non-parametrized constructor parent()
Exception in thread "main" java.lang.Error: Unresolved compilation problem:
Implicit super constructor Parent() is undefined. Must explicitly invoke another constructor
at Child.<init>(InheritanceExample.java:14)
at InheritanceExample.main(InheritanceExample.java:22)
Can you please explain me what is the purpose of the constructor without parameters in base class.
class child extends parent
{
child(int a,int b)
{
int c=a-b;
System.out.println("Difference="+c);
}
}
The first thing the child class constructor must do is call the parent class constructor.
If you do not do this explicitly (e.g. super(a,b)), a call to the default constructor is implied (super()).
For this to work, you must have this default constructor (without any parameters).
If you do not declare any constructors, you get the default constructor. If you declare at least one constructor, you do not get the default constructor automatically, but you can add it again.
The error message you are getting is complaining about the implied call to super() not working, because there is no such constructor in the parent class.
Two ways to fix it:
add a default constructor
in the first line of the child constructor, call a non-default parent constructor (super(a,b))
Also, please don't use all-lowercase class names.
The reason it is asking for parent() is because child extends parent, but you do not explicitly call super(a,b) in the child constructor. Since there is no explicit call to the parent constructor, javac tries to call the default constructor parent() and complains when it can't find it.
You can see this with this code:
class parent
{
public parent() {
System.out.println("Parent Constructor");
}
public parent(int a,int b) {
int c=a+b;
System.out.println("Sum="+c);
}
public void display() {
System.out.println("Return Statement");
}
}
class child extends parent
{
public child(int a,int b) {
int c=a-b;
System.out.println("Difference="+c);
}
}
public class InheritanceExample
{
public static void main(String args[]) {
child c=new child(2,1);
c.display();
}
}
Output:
Parent Constructor
Difference=1
Return Statement
Also, this works fine with no default constructor:
class parent
{
public parent(int a,int b) {
int c=a+b;
System.out.println("Sum="+c);
}
public void display() {
System.out.println("Return Statement");
}
}
class child extends parent
{
public child(int a,int b) {
super(a,b);
int c=a-b;
System.out.println("Difference="+c);
}
}
public class InheritanceExample
{
public static void main(String args[]) {
child c=new child(2,1);
c.display();
}
}
Output:
Sum=3
Difference=1
Return Statement
I think there was a similar question at:
Why should the derived class constructor always access base class constructor?
You can think of it this way: since "child" inherits from "parent", "child" must also be a valid instance of "parent" (polymorphism) before it can behave as a "parent" itself. As such, the very first thing "child" must do is construct itself as a valid "parent" - so a call to "parent"'s constructor via super() must be the first method call in the constructor. If no such call is present, an implicit call to the no-parameter constructor of "parent" results.
The error is there for the reason that if we do not call super explicitly then JVM puts super() in the constructor of the child class and this super() searches a constructor in parent class without parameter which is not in your class so it is wrong. Either put a non parametrised constructor in parent class or put the statement super(a,b) in the very first line of the child constructor.
class Parent
{
Parent(int a, int b)
{
int c = a + b;
System.out.println("Sum=" + c);
}
void display()
{
System.out.println("Return Statement");
}
}
class Child extends Parent
{
Child(int a, int b)
{
super(a,b);
int c = a - b;
System.out.println("Difference=" + c);
}
}
class InheritanceExample
{
public static void main(String args[])
{
Child c = new Child(2, 1);
c.display();
}
}
public class Mobile{
private String manufacturer;
private String operating_system;
public String model;
private int cost;
Mobile(String man, String o,String m, int c){
this.manufacturer=man;
this.operating_system=o;
this.model=m;
this.cost=c;
}
public String getModel(){
return this.model;
}
}
public class Android extends Mobile{
Android(String man, String o,String m, int c){
super(man,o,m,c);
}
public String getModel(){
return "This is Android mobile" +model;
}
import java.io.*;
public class XXX
{
public static void main()throws IOException
{
System.out.println("Enter your name.");
String name = in.readLine();
System.out.println(name+" rules!! Thank You!!");
}
}

Categories