Java Inheritance move common getter to parent - java

I have children classes that use composition with classes that are also children. Instead of having a similar getter in each child class how can I move the getter of the composition class to the parent.
public class child1 extends Parent {
private CoolObjectTypeAAA coolObject;
//coolObject getter
}
public class child2 extends Parent {
private CoolObjectTypeBBB coolObject;
//coolObject getter
}
public class CoolObjectTypeAAA extends CoolObject {
}
public class CoolObjectTypeBBB extends CoolObject {
}
public abstract class Parent {
//would like to have a single CoolObject getter here in parent that returns the appropriate cool object of each child.
}
Is this possible or do I need to just have similar getter in each child class?

How about this:
abstract class Parent<T extends CoolObject> {
protected T mCoolObject;
public Parent(T coolObject) {
mCoolObject = coolObject;
}
public T getCoolObject() {
return mCoolObject;
}
}
class Child1 extends Parent<CoolObjectTypeAAA> {
public Child1(CoolObjectTypeAAA coolObject) {
super(coolObject);
}
public void demoType() {
// This type checks as the return type of getCoolObject() has been refined to CoolObjectTypeAAA
CoolObjectTypeAAA co = this.getCoolObject();
}
}
class Child2 extends Parent<CoolObjectTypeBBB> {
public Child2(CoolObjectTypeBBB coolObject) {
super(coolObject);
}
public void demoType() {
// This type checks as the return type of getCoolObject() has been refined to CoolObjectTypeBBB
CoolObjectTypeBBB co = this.getCoolObject();
}
}
abstract class CoolObject { }
class CoolObjectTypeAAA extends CoolObject { }
class CoolObjectTypeBBB extends CoolObject { }
Essentially you make the subclass specify whatever specific subtype of CoolObject it uses so that it can refine the return type of the getter, yet you get to implement the getter in the super class.

I would suggest taking a look at the abstract factory pattern as this seems to be what you are trying to accomplish. Properly implemented it involves multiple abstract classes and many subclasses but it is not as daunting as it seems.
What you are trying to do basically looks like a compact version of this but it is generally not a great approach as it leads to difficult to follow OO spaghetti code that jumps back and forth between the parent and subclass.
Remember, you've already defined Parent as abstract for a reason.
I suspect your goal is to maximise code reuse, normally when I see this kind of code it is because there is some common "CoolObject" init code that you don't want to duplicate in the child classes.
In that case, it is typically better to write a common "CoolObject" private or protected initializer in the parent but still construct the specific type of CoolObject in the child classes and then initialize it via the parent class method before returning it from the child.
In this case, since it is a getter, there may not be anything other than returning the private object. If that is the case then the best thing is to define a generic getter as abstract in Parent and then redefine in each child. The primary issue with this is that wherever you use this code you will need to continually typecast to the specific type of CoolObject you are expecting.
Because of this, it is likely that down the line, even if you provide either an abstract CoolObject getter or a concrete CoolObject getter in Parent, you will still end up wanting to have concrete implementations of getters for the specific CoolObject types.
The thing to keep in mind when designing something like this is how is it going to be used.
If the goal is to provide an abstraction over the various types of CoolObject then you are basically using a strategy pattern. In this case, being able to cast variables to the sub-type of CoolObject is not needed. In that case a non-specific type getter (abstract or concrete) is feasible.
Having the two specific child classes of Parent, however, it doesn't feel like this is what you are going for. Again I would suggest taking a look at the abstract factory pattern as this seems more like what you trying to do.

Related

Converting Class of an Object into a Child Class

Say I have the following classes
public abstract class Parent {
public Parent() {
//stuff here
}
}
public class Child extends Parent {
public Child() {
//stuff here
}
public void doSomething() {
}
}
Then I get an object from an array of Parents
public Parent[] parents = new Parent[5];
Parent tempParent = parents[0]
If this object is of the child class, I want to cast the tempParent into the child class in order to use "doSomething" without having to create a new object
if(tempParent.getClass == Child.class) {
tempParent = (Child) tempParent;
tempParent.doSomething();
}
This, however, does not work. I still get an error telling me that doSomething is not a function in the Parent class. Is there a way to do what I'm trying to do?
You need to use the correct TYPE on the LEFT hand side:
Child someChild = (Child) tempParent;
Note: this does not create a new Object.
There is no way of having
Parent whatever = (Child) tempParent;
do what you want to do (invoke a Child class method)!
You see, the compiler only cares about the "defined" type of your reference, it does not take into account that you most likely, at runtime, just "put" something into that reference that in deed is a Child instance!
to do what you want to do.
And note: do not compare objects using ==. You should prefer to call equals() instead. For Class objects == should work (most of the time), but still: get used to check for equality using equals().
I think you're trying to solve the issue from the wrong side.
Technically speaking you should do it like this.
public abstract class Parent {
public Parent() {
//stuff here
}
public abstract void doSomething();
}
public class Child extends Parent {
public Child() {
//stuff here
}
#Override
public void doSomething() {
// Write the code of doSomething specific to child.
}
}
A bit off topic but you might want to consider the following:
I think that the class representation of your code is bad.
I think that you should have 2 concrete classes Parent and Child that are composed or either inherit from a common interface. Even better use composition over inheritance.
https://en.wikipedia.org/wiki/Composition_over_inheritance
if you are able to modify the parent class, I would recommend that you make doSomething an abstract method and have the child class override it. that way, there is no need to cast in order to invoke it.
https://docs.oracle.com/javase/tutorial/java/IandI/abstract.html

Handling inheritance with Parent Class and Child Classes with nested objects

Suppose I have a class Child extending Class Parent. The class Child has two nested classes nested1 and nested2. I want a abstract function to be defined in Parent with argument as nested1 and return type as nested 2. Right now , to achieve this , I have created a function with both argument and return type as Object.
So now , when I implement the child class , I am always required to cast the Object to nested1 and nested2. I feel there would be a better way to achieve this. Is there any better way to reduce the complexity?
Also attached the UML
The best way from a typing point of view is to make a interfaces within the parent class that specify the nested classes in the child. That way you won't need to cast the argument to func. This doesn't reduce the complexity per-se but it does make your intention a lot cleaner and reduces/eliminates the need for casting (always a good thing).
public abstract class Parent {
interface Interface1 {
//Specifications of methods that all child nested classes must have
}
interface Interface2 {
//Specifications of methods that all child nested classes must have
}
public abstract Interface2 func(Interface1 obj);
}
public class Child extends Parent {
private static class Impl1 implements Interface1 {
//Implementations of methods in Interface1 as they pertain to Child
}
private static class Impl2 implements Interface2 {
//Implementations of methods in Interface2 as they pertain to Child
}
#Override
public Interface2 func(Interface1 obj) {
//Should only have to use methods declared in Interface1
//Thus should have no need to cast obj.
//Will return an instance of Impl2
return null;
}
}
On a more broad scale, you should ask yourself why every child needs its own set of nested classes. This will get way simpler if you can move the nested class definitions to the parent (and make them static) and just have the child classes customize them as needed during construction.

What is the best practice in Java to set a constant required in subclasses?

I have the following situation:
A parent class has a function that depends on a constant. But the only valid place to define that constant is in subclasses (parent class cannot define the constant's value, but it can be used with the constant undefined in 99% of use cases - the constant is a default to use if a specific configuration element is missing).
However, I would like to enforce that any child class inheriting from that parent class must define the value for the constant, since any child classes have to be able to use the other 1% of functionality.
What is the best practice to implement this enforcement in Java, ideally at compile time? (clearly, at runtime, I can simply check if the constant is null/empty in the method using it).
My own solution was to implement a value-getter for the constant as an abstract method in the parent class, and call that in combination with the real setter in the constructor; something like this:
public class HelperClass1 {
private String myConstant;
public void setMyConstant() {} // implemented obviousy
public void myMethod() { // Called from ParentClass's methods
// Do something useful with myConstant
}
}
import HelperClass1;
public abstract class ParentClass {
ParentClass() {
HelperClass1.setMyConstant( getMyConstantValue() );
}
public abstract void getMyConstantValue();
}
public class ChildClass1 extends ParentClass {
public void getMyConstantValue() { return "BUZZ"; }
}
public class ChildClass2 extends ParentClass {
} // Fails to compile without getMyConstantValue()
However, (a) This implementation has a problem (I can't use ParentClass itself, since it's now abstract) without subclassing; and (b) since I'm not a Java developer, I'm afraid that this isn't the best or the most elegant solution. So I'd like to know if there's a best practices approach that improves on what I implemented.
Provide two constructors for the parent class:
One is a protected constructor which takes the constant as an argument.
The other is private constructor which can construct instances of the parent class without setting the constant.
Provide a factory method for the parent class which can call the private no-constant constructor.
Classes that want to get an instance of the parent class can call the factory method. But child classes that want to inherit from the parent class have to call the protected constructer, which can validate that a valid constant was passed.
public class ParentClass {
private final SomeClass myConstant;
protected ParentClass(SomeClass aConstant) {
if (null == aConstant) {
throw new IllegalArgumentException("...");
}
myConstant = aConstant;
}
private ParentClass() {
myConstant = null;
}
public static ParentClass getInstance() {
return new ParentClass();
}
}
public class ChildClass {
public ChildClass() {
super(new SomeClass(42));
}
}
This isn't perfect. Someone could write a child class that passes a bad constant to the superclass constructor, and it wouldn't actually fail until some code tried to construct an instance of the child class.

Java - Can the children of an abstract class (the "extends"-ers) instantiate themselves via their parents abstract method?" i.e. m = new this();"?

First things first, please be aware I am trying to express my question as best I can with my current knowledge and vocabulary, so please excuse this...
I have an abstract class in which I want to make a method where it instantiates itself.... Of course this is impossible in an abstract class, however, what I really want is for the concrete children (those classes that "extends") to inherit this instantiation so that they then can instantiate themselves....
Basically what I want to do is this:
MyAbstract a = new this();
However this isn't allowed... Is there any way I can do what I want?
Here is some non-compiling dream-code (i.e. code I wish worked). Basically I am wanting the ConcreteChild to call a method in which it create an object of itself. The method is inherited from it's parent.
public class Abstract {
public void instantiateMyConcreteChild()
{
Abstract a = new this();
}
}
public class ConcreteChild extends Abstract{
public static void main(String[] args) {
ConcreteChild c = new ConcreteChild();
c.instantiateMyConcreteChild();
}
}
* Additional info **
Thanks for the replies but I think I missed something vital....
Basically I wanted to pass an object's self ( "this" ) into some methods of some other classes. However, creating instantiating another object within an object is a bit backwards, I can just pass "this", right...
You can do this using reflection, something like :
Abstract a = getClass().newInstance();
This is because getClass() always returns the concrete class, so this.getClass() will return the real subclass and not the current class.
However, beware that if the subclass defines a custom constructor, having more or less parameters than your abstract class, it could fail. Unless you specify in the documentation that subclasses must have a constructor with such given parameters ... but it's fragile anyway.
You can inspect it, using getClass().getConstructors() and see which constructors are there, and if there is the one you are expecting, or even search for a viable one, otherwise you can catch the exception thrown by newInstance(..), and wrap it in a more descriptive exception for the users, so that they understand better what they missed ... but it would still be a kind of a hack, cause there is no explicit language support for such a situation.
Another approach could be to implement Cloneable in your abstract class, and then use the clone method, but it could be overkill or even wrong if what you want is a new, clean instance.
You can't do this using an instance method. Because as the name implies an instance methods requires that the instance has already instantiated.
What you actually need to do here is to separate the non-changing internal functionality from the abstract class itself. So what I could do is to ,for e.g., have an inner class that really encapsulates the non-changing functionality like so:
public class Abstract {
public void instantiateMyConcreteChild()
{
Abstract a = new NonChangingOperations();
}
class NonChangingOperations
{
public void operationA() {}
}
}
Infact you really dont need to keep the class NonChangingOperations as an inner class, you could make it as an external utility class with its own class hierarchy.
Are you trying to define a constructor that the subclasses of Abstract can use? If so you could simply do it the same way you define any other constructor.
public class Abstract {
Abstract() {
//set fields, etc. whatever you need to do
}
}
public class ConcreteChild extends Abstract{
ConcreteChild() {
//call superclass's constructor
super();
}
}
Could you just have this ?
public abstract class AbstractClassWithConstructor {
public AbstractClassWithConstructor() {
init();
}
protected abstract void init();
}
FYI
In the objective-c you need to set this by calling method init. The the method init() would look like this:
protected AbstractClassWithConstructor init() {
return this;
}

Java inheritance

So I've been trying to find the proper way to get what should be pretty straightforward inheritance to function (the way I want ;)) and I'm failing miserably. Consider this:
class Parent
{
public String name = "Parent";
public Parent() {};
public void doStuff()
{
System.out.println(name);
}
}
class Child extends Parent
{
public String name = "Child";
public Child()
{
doStuff();
}
}
I understand that Java doesn't do what I'd expect in this case as for some reason member variables aren't overridden the same way methods are but my question is what is the proper way to achieve the behavior I'd expect? I'd like my base class to contain some functions that operate on member variables provided/defined by a given subclass. I'd think get/sets could work, but then it destroys my ability to just call super() and have my base class do the construction needed making my subclasses contain a bunch of construction instead of isolating it to the base class.
Any constructive suggestions are welcome.
You can always replace a variable with getter, if you want such kind of 'variable-inheritance'. Not sure if 'variable-inheritance' ((c)) is a good design pattern in general, though.
class Parent {
public void doStuff() {
System.out.println(getName());
}
public String getName() {
return "Parent";
}
}
class Child extends Parent {
public Child() {
doStuff();
}
public String getName() {
return "Child";
}
}
Or you could have protected constructor in Parent class, taking the name to use.
edit
I wouldn't call it a 'hack'. And version with passing parameter into parent constructor can be pretty elegant too.
class Parent {
private final String name;
// don't let use to invoke this constructor, only for child classes
protected Parent(String name) {
this.name = name;
}
// public constructor for users
public Parent() {
this("Parent");
}
public void doStuff() {
System.out.println(name);
}
}
class Child extends Parent {
public Child() {
super("Child");
doStuff();
}
}
do you have any idea why Java seems to have abandoned the concept of inheriting member variables?
Java has abandoned a lot of C++ concepts (starting from infamous multiple inheritance), because they didn't add that much value to the language, but increased its complexity.
Although I don't have anything against variable-inheritance, I'm not suffering without this concept either. And personally, I like the language simple and clean.
Do you really need two different name variables for a single instance? Do you genuinely have the idea of an object having a "name-when-viewed-as-Parent" and a "name-when-viewed-as-Child"? If not, just have a single variable in the Parent class.
How would the Parent class know which variables are going to be provided by the child? If every subclass is going to have the same set of variables, why aren't they in the parent class?
If you could give a more concrete example of the problem you're trying to solve, it would make it easier to give a concrete answer.
The subclass variable name is shadowing the super classes variable of the same name. So when Child declares and assigns name it's another separate variable.
Instead, consider name to be a property of the parent inherited by the child and pass name as an argument to the Parent constructor. Then you would invoke super("Child") from the child constructor.
Also, as a public property, it should be final. Otherwise expose it via getters and setters.
You are correct in that you can't override members of the class. You can achieve this by making name protected and setting it in the constructor.
class Parent {
protected string name;
public Parent() { name = "parent"};
public doStuff() {
System.out.println(name);
}
}
class Child extends Parent {
public Child() {
name = "child";
doStuff();
}
}
What you are trying to do won't work in Java. In Java, attributes declared in a parent class are not overridden in a child class.
If you want polymorphic behavior, then you need to declare the attributes private, and declare corresponding getter methods in the parent class that you can override in the child class.
Alternatively:
class Child extends Parent {
public Child() {
name = "Child";
doStuff();
}
}
though #shoebox639's answer does this in a more elegant way that allows you to declare the attribute as final. (Mutable public attributes are not a good idea ...)
You don't need to redefine your member variable in the subclass. You can write your code as #Stephen C says
class Child extends Parent {
public Child() {
name = "Child";
doStuff();
}
}
In your post
I'd like my base class to contain some functions that operate on member variables provided/defined by a given subclass.
You will write your super class at first and at this stage your super class does not know about your subclass.

Categories

Resources