Keeping it DRY when constructor needs to call overridable method - java

As per this question, while I understand why it goes wrong, how can I effectively solve this while keeping my code DRY? I wouldn't want to copy and paste the contents in that function into the constructor.
Suppose I have the following
class Parent
{
Parent()
{
overridableFunction();
}
void overridableFunction()
{ ... }
}
class Child extends Parent
{
Child()
{
super();
overridableFunction()
}
void overridableFunction()
{ ... // overridden }
}
Ideally, I wish the execution flow of the Child constructor to be
Parent() --> Parent.overridableFunction() --> Child.overridableFunction()
How can I achieve this without copying and pasting stuff around thus making the code WET?

If you wish Parent's constructor to execute its own implementation of overridableFunction() and Child's constructor to execute its own implementation of overridableFunction(), what you are basically saying is you don't want Child's overridableFunction() to override Parent's overridableFunction() method.
You can give the two methods different names, or keep the names identical, but make Parent's method private, to avoid any overriding.

I am not sure why you want to do it, but this follows the execution flow you asked for :
class Parent
{
Parent()
{
overridableFunction();
}
void overridableFunction()
{ System.out.println("Parent implementation "); }
public static void main(String[] args) {
new Child();
}
}
class Child extends Parent
{
Child()
{
super();
//remove overridableFunction();
}
#Override
void overridableFunction()
{
super.overridableFunction();
System.out.println("Child implementation ");
}
}

Related

Can anyone explain why below o/p

Parent class :
public class Parent {
public void run()
{
walk();
System.out.println("Parent run");
}
public void walk()
{
System.out.println("Parent walk");
}
Child Class :
public class Child extends Parent {
public void run()
{
super.run();
System.out.println("child run");
}
public void walk()
{
super.walk();
System.out.println("child walk");
}
public class FirstJava {
public static void main(String[] a) {
Child c=new Child();
c.run();
}
I am gettting below o/p
Parent walk
child walk
Parent run
child run
Here when i call walk() its going for walk() of Child.
Why not for walk() of parent?
While calling walk() which object its refering to and why? any one explain why??
how come its calling both the methods from child as well as parent.
in
Child c=new Child();
c.run();
you apply run corresponding to the type of the value in c, because c values a Child and run is defined on it you call the operation run defined on Child being :
public void run()
{
super.run();
System.out.println("child run");
}
super.run() applies the operation corresponding to the parent class, because the parent class of Child is Parent and run is defined on it you call :
public void run()
{
walk();
System.out.println("Parent run");
}
the operation walk is applied depending on the real type of the instance being Child so you call :
public void walk()
{
super.walk();
System.out.println("child walk");
}
like before because of super that calls the operation on Parent :
public void walk()
{
System.out.println("Parent walk");
}
printing Parent walk then you come back in Child walk printing child walk then come back in Parent run printing Parent run then come back in Child run printing child run
After your edit
Here when i call walk() its going for walk() of Child. Why not for walk() of parent? While calling walk() which object its refering to and why?
As I already say this is because the called method is determined (at the execution) by the real type of the instance, and in that case the instance is a Child, so the called method is the walk defined on Child and not the one on Parent. Of course if there is no walk defined on Child it would be the one defined on Parent. All the method are applied on the unique instance you created in main and being a Child
Of course if walk is a method for the class Parent (e.g. static) rather than for its instances that changes all and walk() in run of Parent would be the walk of Parent. But this is not the case in your code so the real type of the instance counts.
Note also the execution would the all the same modifying your main to have :
public class FirstJava {
public static void main(String[] a) {
Parent c=new Child();
c.run();
}
because even c is declared Parent its value is a Child
If you override a parent method in its child, child objects will always use the overridden version.

calling subclass method after initialising to parent java

This might (most certainly will) sound stupid, but I am stuck and I cant find a proper solution to my problem.
I have a superclass and two sub classes extend it. On the parent class based on a condition I want to call the method from either of the two classes. This is inside a loop, so instead of doing the same check I decided to do the check once, create an object from the super class and then change the object to either one of the two sub classes. i.e.
public class Parent{
public void method() {
Parent object=new Parent();
if(a==b) {
object=new Child_A();
}else {
object=new Child_B();
}
for() {
object.method();
}
}
public void method() {
//empty method. need it just to compile
}
}
public class Child_A extends Parent{
public void method() {
//do something useful
}
}
public class Child_A extends Parent{
public void method() {
//do something useful
}
}
I had to write the Parent.method(), cos otherwise the compile would complain that there is no method() method on class Parent.
So with this, the method called is not one of the children,but the parents method.
I have read that objects need to be assigned directly to the class, like Childen_A object=new Childen_A. The thing is that I would like to use the same command for both cases (object.method()) no matter which class it refers to. Strange thing is that during debug, i see that object is of type Child_A, nevertheless the super method is called.
I know that the solution would be to create two different objects, one for each sub class, but that would make my code a bit more ugly and i would have to use the if statement inside the loop.So the correct way of doing it must be
public void method() {
for() {
if(a=b) {
Child_A object=new Child_A();
object.method();
}else {
Child_B() object=new Child_B();
object.method();
}
}
}
Is there a way to avoid the if statement inside the loop? Thanks
Your code should be
public class Parent {
public void method() {
}
// OR
public abstract void method(); // and make the class abstract as well
}
public class Child_A extends Parent {
#Override
public void method() {
//do something useful
}
}
// same with Child_B

Why bother using abstract method and overriding while we can always use a generic method in the superclass?

The following is a popular use case involving abstract method and overridding.
class Demo {
public static void main(String[] args) {
Parent a = new Child_A();
Parent b = new Child_B();
a.method();
b.method();
}
}
abstract class Parent {
abstract void method();
}
class Child_A extends Parent {
#override
void method() {
do the task for Child_A;
}
}
class Child_B extends Parent {
#override
void method() {
do the task for Child_B;
}
}
It seems that we can always achieve the same thing by defining a generic method in the superclass, which uses the instanceof keyword to determine the subclass and performs the corresponding task for the subclass.
class Demo {
public static void main(String[] args) {
Parent a = new Child_A();
Parent b = new Child_B();
a.method();
b.method();
}
}
class Parent {
void method() {
if (this instanceof Child_A) {
do the task for Child_A;
}
else if (this instanceof Child_B) {
do the task for Child_B;
}
}
}
class Child_A extends Parent {
}
class Child_B extends Parent {
}
Which code style is better and why?
Because:
you don't want to have to modify the parent class every time you add another subclass
in some circumstances like a library API you may not even know all the subclasses
code that deals with a subclass should be in that subclass, not in the parent.
If you do the latter, your subclasses becomes useless. They don't do anything. I'd like to think of it this way, the parent passed you the ability to do methodA in your own way. However in your case, the parent does everything, meaning you are dependent on your parent forever. Who would want that?
Well aside from that, when you create a new subtype, you'll have to edit also the parent(very absurd), think of what will happen 100 subtypes later. Give your subtypes the power to have their own individuality.

How can i break the inheritance nature in java?

I have below parent class :-
class Parent {
Parent() {
System.out.print("Parent ");
}
}
class Child extends Parent {
Child() {
System.out.print("Child");
}
}
So when i execute Child c = new Child();
My output should be "Child" Not "Parent Child"
can we do that using reflection API?
Requirement :-
I have a long Junit Setup hierarchy Which I want to avoid for some of the classes
What happens is when you create the Child class the Parent's class constructor is called first and then the Child's constructor.
What you could do if you must change what happens in the parent constructor is that you extract the related code into a protected method and this way you can override it in the Child class
However it is error prone and not recommended (What's wrong with overridable method calls in constructors?)
class Parent {
Parent() {
overridableInit();
}
protected void overridableInit() {
System.out.print("Parent ");
}
}
//If you want to extend the behavior:
class Child1 extends Parent {
#Override
protected void overridableInit() {
super.overridableInit();
System.out.print("Child1 ");
}
}
//If you want to skip the Parent behavior:
class Child2 extends Parent {
#Override
protected void overridableInit() {
System.out.print("Child2 ");
}
}

could parent object be created using super to call parent method

Would the parent object be created , if we use the super keyword to call the method of the parent class in child object?
Outcomes show that both Mybase and MySub have the same reference address. Not sure whether it is a good demo.
class Mybase {
public void address() {
System.out.println("super:" + this);
System.out.println( this.getClass().getName());
}
}
class MySub extends Mybase {
public void address() {
System.out.println("this:" + this);
System.out.println( this.getClass().getName());
}
public void info() {
System.out.println("this:" + this);
super.address();
}
}
public class SuperTest {
public static void main(String[] args) {
new MySub().info();
}
}
Well, let's find out!
Your test isn't quite going to answer your question. If you want to see if an object is created, why not create a constructor that prints to the console when called?
public class Test {
static class Parent {
Parent() {
System.out.println("Parent constructor called");
}
void method() {
System.out.println("Parent method called");
}
}
static class Child extends Parent {
Child() {
System.out.println("Child constructor called");
}
#Override
void method() {
System.out.println("Child method called");
super.method();
}
}
public static void main(final String[] args) {
new Child().method();
}
}
If you run this, you get this output:
Parent constructor called
Child constructor called
Child method called
Parent method called
So as you can see, when method() was called, no Parent object was created when the super keyword was used. So the answer to your question is "no".
The reason is because super and super() are different. super (no parentheses) is used to access members of the parent class. super() (with parentheses) is a call to the parent constructor, and is only valid inside a constructor as the first call in the constructor. So using super (no parentheses) will not create a new object.
Also, super() doesn't actually create a new, independent Parent object. It just does the initialization work for the fields of Parent that is needed before the child constructor continues.

Categories