Java abstract method in constructor

Java — Issue with calling abstract method during instantiation in super before child fields have been set

This is my first time using these forums, so I hope this thread is appropriate and that I don’t mess up. This is in Java — I’ll try and simplify the example to focus on the main problem. Any help would be appreciated! Say I have two classes, Parent and Child, where Parent is an abstract class and Child extends Parent. (I’m writing this code on the fly).

public abstract class Parent < // A bunch of fields that have been omitted. public Parent() < print(getX()); >public abstract int getX(); > 
public class Child extends Parent < private int x; public Child(int x) < super(); this.x = x; >@Override public int getX() < return x; >> 

I want to instantiate Child, and call an abstract method immediately after instantiation. Obviously, currently there is an issue because the x field hasn’t been set when getX() is called in the parent from super(), and therefore will always return 0. However, I want this to be done in the parent for all children of Parent (if there is a Child2, Child3, etc. that extend Parent in the future). i.e. anything that extends Parent will have their «x» value printed. The work around to this would be to print getX() with every Child that is instantiated, but for some reason, it seems rather off to me to have to do this repeatedly inside every Child class, as opposed to having this captured in the Parent. Any suggestions as to how I should approach this (calling an abstract method during instantiation)? Design pattern or design changes? Use the repeated call in the Child? Thanks 🙂

First hello OshaGoro! That is a very good formulated question, and in that regard, you did well for your first one! 🙂

When every Child has x then x belongs to Parent , not Child . Move x to Parent and create a constructor with a parameter for it.

If every child class has x then it should be defined in Parent class. You can have a setter method so as sub classes can set its value. Or you could mark it with access modifier as protected . Now regarding the invoking overridden field-getter method from constructor of Parent class doesn’t make sense as if the field is not set by parent then always you will get the default value only. Overridden method as a good practice shouldn’t be invoked from constructor.

1 Answer 1

As akuzminykh correctly stated, if the x field is part of all classes derived from Parent , then the field is a Parent field. However sometimes this is not the case, and then you would want the child fields to be set, before the parent is completely living.

This is a common problem in instantiation order, and as you stated correctly:

[. ] there is an issue because the x field hasn’t been set when getX() is called in the parent from super() [. ]

Due to this, that kind of call cannot be made inside a parent constructor. There are some common approaches to this, most involving some kind of init() method being called, after the instance has been completely constructed.

One pattern doing this (without the use of heavy weight dependency injection) is the factory pattern. See https://www.tutorialspoint.com/design_pattern/factory_pattern.htm for detailed information.

Читайте также:  User interface with python

The Factory pattern is designed in such a way, that an instance is not only created by a constructor, but ultimately returned by a factory, which is given values that are used for instantiation. That factory can guarantee the call of an init -method, after the instance is completed.

abstract class Parent < // Notice the protected modifier! protected Parent() < // field initializations of Parent. >protected void init() < // I replaced print with System.out.println here ot make it compile. System.out.println(getX()); >public abstract int getX(); > abstract class ParentFactory  < public abstract T instance(); >public class Child extends Parent < private int x; protected Child(int x) < super(); this.x = x; >@Override public int getX() < return x; >> class ChildFactory extends ParentFactory  < int x = 0; public void setX(int x) < this.x = x; >@Override public Child instance() < Child instance = new Child(x); instance.init(); return instance; >> @Test public void test()

Notice that this kind of factory (a stateful factory) is very similar to a Builder from the Builder pattern. It is different only in that it is usually reused, rather than created on the spot. You can vary this pattern in that there is also an explicit method in ChildFactory which takes explicit parameters over the state-fields of ChildFactory:

public Child instance(int x)

Источник

Abstract method in the class constructor

Since you are instantiating a Circle, this will point to the overriden implementation in your Circle class Solution 4: The answers of Jon skit and Eyal Schneider’s from following post can be the possible answers for this question- State of Derived class object when Base class constructor calls overridden method in Java Question: I was wondering what was the design considerations in java that prevented classes like this? So: Question: I have abstract class Shape as below which contains abstarct method calc — Another class Circle which extends Shape — And now the Final main class- Output when run the main class — from shape from calc in circle from circle I understand that when we create object of child class the construtor of parent class will be called.

Abstract method in the class constructor

I want to implement an Abstract Java class. One of the abstract methods must be implemented by each child class, to ensure that that part of the code will be executed individually in each child class. Is there any other way to do it and thus avoid the «warning» that appears by calling an abstract method from the constructor of the main class?

 public abstract class Listener < protected Date checkTime = new Date(); protected TypeUpdate type = UNKNOW; public Listener()< super(); this.setTypeListener(); >public void setTime(Date date) < if (date != null) < return; >this.checkTime = date; > /* Abstract methods */ public abstract void execute(); protected abstract void setTypeListener(); > 

Ok, It’s an error call an abstract method in constructor. So, what can I do to force inheriting classes to make a concrete constructor implementation (for example, initialize a member in one way or another?)

You are arriving in the Base class constructor and on returning from that constructor, in the child class constructor all field initialisations will happen and the remaining code form the child constructor.

To ensure that some method is called you can either call that method lazily later. Or pass an independent object, as «part» of the entire child.

public Child() < super(createPart()); >private static Part createPart() < return new Part().withAnswer(42); >public Base(Part part)

One may also have a case of

class Base < public final void foo() < onFoo(); >protected void onFoo() < throw new IllegalStateException("Missing onFoo implementation " + getClass().getName()); >> 

Constructor in Abstract method [duplicate], It’s there for concrete subclasses to use. class SubEmployee extends Employee < public SubEmployee(String name, String address,

Читайте также:  What is java hibernate tutorial

Abstract Method called in its class’s constructor

I have abstract class Shape as below which contains abstarct method calc —

public abstract class Shape < public Shape()< System.out.println("from shape"); calc(); >public abstract void calc(); > 

Another class Circle which extends Shape —

public class Circle extends Shape < public Circle()< System.out.println("from Circle"); >public void calc() < System.out.println("from calc in circle"); >> 

And now the Final main class-

Output when run the main class —

I understand that when we create object of child class the construtor of parent class will be called. What i am confused about is how the call to calc method in shape’s constrcutor works as we dont have any implementaion for the calc in shape class.

From the output it seems it is calling the overridden calc method from the child class circle but how does that works ??

That’s how polymorphism and inheritance work. It’s important that you understand it if you’re going to write object-oriented code.

The simplest explanation is to imagine that there’s a method table that says «I know I’m an abstract class at compile time, but at run time I know that I’m a concrete child class. Look up the child’s version of that method in the method table and call it.» There’s a measure of indirection that goes on at run time.

Imagine it as a call to this.calc() . It doesn’t call the method calc of the same class, it calls the method calc of this , and this is a Circle object.

You instantiate a Circle class in your test.

So what is happening in your Circle instance:

  • Circle constructor is called
  • super constructor is called
  • super constructor calls calc() method
  • calc() method of your Circle(!) instance is called

Note that you didn’t instantiated a Shape but a circle. The crucial part then is really understanding how method overriding is working in OO: the calc() method is really just a virtual pointer to your actual implementation. Since you are instantiating a Circle, this will point to the overriden implementation in your Circle class

The answers of Jon skit and Eyal Schneider’s from following post can be the possible answers for this question-

State of Derived class object when Base class constructor calls overridden method in Java

Constructors in Java Abstract Classes, A constructor is a method called when a class is instantiated, and an abstract In this article, we’ll see why abstract classes can have

Why can’t we have abstract constructor in java?

I was wondering what was the design considerations in java that prevented classes like this?

If we could force implementation of constructors,then we could instantiate abstract classes. But why didn’t they? Does this violate OOP design or is it simply not possible?

An abstract constructor would have no meaning.

An abstract method forces all concrete sub-classes to implement a method of the same signature (which includes the same name).

However, a concrete sub-class can’t implement a constructor having the same name as the «abstract constructor» of the abstract class, since a constructor must have the name of the class in which it appears.

An abstract modifier is meant for those whose implementation is yet to be given.

Considering a situation (like the one you just asked) the constructor itself is abstract so its class creation cannot actually happen.

Читайте также:  Directory not exists java

For a class to exist its default constructor will be invoked by the the system automatically. But now as you have provided your own constructor (which additionally is abstract), the default one won’t exist and hence this class won’t exist.

Hence an inconsistent situation to be in.

You can’t have an abstract constructor, as abstract means you need to provide the implementation for that at some point of time in your subclass. But you cannot override constructor. There will be no point in having an abstract constructor :

  1. Since the constructor needs to be of the same name as of class.
  2. You will always call the constructor of child class and not of base class

Abstract constructor will have no meaning, since constructor is directly related to object creation of a particular type. Also there is no way by which we can define a constructor for any other class from a given class.

But if you still want to enforce this kind of pattern, you need to go with the abstract factory pattern

When you set a constructor as ‘abstract’, you are essentially saying:

This constructor doesn’t have a body and you want to implement it at another time in a child class

However, the constructor is called implicitly when an Object is created, so we can’t implement the constructor that’s why constructors are not abstract.

Accessing fields/methods/constructors of an abstract class in its, Yes, an abstract class can have a constructor. It needs to be called by any subclass constructor. Is the keyword «this» necessary in this

Java abstract class, abstract constructor

I’m trying to find a way to force the user that will implement an interface or will extend a class to create several constructors. I thought that a way to do that would be to create an abstract constructor in an abstract class, but I figured out that I can’t do that.

How can I solve this issue? Is there some method to force the user to create a specific constructor?

No. But, as Constructors are often substituted by factorymethods anyway, you could implement abstract factorymethods or just other patterns like the builderpattern.

You can’t create an abstract constructor, but here’s a workaround that you can do:

Implement an abstract class with all the constructors you want the user to implement. In each of them, you will have a single statement that refers to an abstract method from this class, which implementations will be in the subclass. This way you will force the user to provide a body for the constructor, via the abstract method implementation. For example:

public abstract class MyAbstractClass < public MyAbstractClass(int param) < method1(param); >public MyAbstractClass(int param, int anotherParam) < method2(param, anotherParam); >protected abstract void method1(int param); protected abstract void method2(int param, int anotherParam); > 

In the implementation, you will be forced to provide implementation of these two methods, which can represent the bodies of the two constructors:

public class MyClass extends MyAbstractClass < public MyClass(int param) < super(param); >public MyClass(int param, int anotherParam) < super(param, anotherParam); >public void method1(int param) < //do something with the parameter >public void method2(int param, int anotherParam) < //do something with the parameters >> 

However you could build a unit test framework that exploits reflection to ensure that the correct constructors are present.

Why Does An Abstract Class Needs A Constructor?, If it is a class, it can have a constructor to initialize its properties. But hold on, we know that abstract class can never be

Источник

Оцените статью