Java dispatch to child class when variable is of abstract parent class - java

I have an abstract parent class Parent and six child classes ChildA though ChildF.
Another class Other has a six (static) overloaded methods olmeth(), one for each of the six child classes.
How can I write:
Parent message = Factory.returnRandomChildClass();
Other.olmeth(message);
At the moment I use an extra method, overloaded for the parent class, and six instanceof checks to work around this issue. This is unscalable.
How can I get Java to dispatch on the actual type of message, rather on the type of the reference to the message?

Make an abstract method in the Parent, and let each child dispatch to its own static overload:
abstract class Parent {
protected abstract void send();
}
class ChildA extends Parent {
protected void send() {
Other.olmeth(this);
}
}
class ChildB extends Parent {
protected void send() {
Other.olmeth(this);
}
}
...
class ChildF extends Parent {
protected void send() {
Other.olmeth(this);
}
}
Note that although the code in all six implementations of send() look exactly the same, the methods actually dispatch to six different overloads of Other, because the static type of this in each case is different.

Use double dispatch pattern. Implement the olmeth logic for every Parent child class and change your current olmeth method to this:
static void olmeth(Parent p) {
p.olemth();
}

Related

Calling child constructor interlaced in parent constructor in java

I have lots of children to a base class and plan for adding a lot more. I'm lazy. The child creator sets up some basic things that is needed for the super constructor and vice versa. A simple solution from my problem would be the following:
parent {
public parent(){/*some code*/}
public void finalSetup(){/*code that dependent on the fact that the child constructor has run*/}
}
child{
public child(){/*some code;*/ super.finalSetup();}
}
How ever, calling super.finalSetup() on every child is quite the hassle, and if I forget it on one it'll break. That's no good. My question is simple: is there any way to set this up form the parent. As far as my google skills go I haven't been able to find one. Hopefully you guys know something I don't.
Thanks
Consider the Factory pattern to create generic type that extends Parent.
public class Parent {
public Parent(){/*some code*/}
public void finalSetup(){/*code that dependent on the fact that the child constructor has run*/}
public static <T extends Parent> T makeChild(Class <T> klass) {
T child = null;
try {
child = klass.newInstance();
child.finalSetup();
}
catch (InstantiationException| IllegalAccessException ex) {
// somthing went wrong
}
return child;
}
}
and call
Child child = Parent.makeChild(Child.class);
It is useful when:
+ a class can't anticipate the class of objects it must create
+ a class wants its subclasses to specify the fields or objects it creates
+ classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate
This should be what you want, but as already mentioned, it can be not the best idea. You don't need to explicitly call the parent constructor in your subclass if you have a no-argument constructor in your superclass.
abstract class Parent {
Parent() {
/*some code*/
childInit();
finalSetup();
}
void finalSetup() {/*code that dependent on the fact that the child constructor has run*/}
abstract void childInit();
}
class Child extends Parent {
#Override
void childInit() {
/* the code you would put in child's constructor */
}
}
This should do it. The basic idea is to override the before and after methods in your children and in the parent constructor you simply run both and do some initialization in between. Of course this does not save you from forgetting to call the parent constructor.
abstract class Parent {
Parent(){
doBefore();
// some stuff
doAfter();
}
abstract void doBefore();
abstract void doAfter();
}
class Child extends Parent {
Child(){
super();
}
void doBefore(){
// do before stuff
}
void doAfter(){
// do after stuff
}
}
With abstract methods in your parent you can implement any permutation of before / after procedures.

How to create custom class from variable? (not Object)

I know I can do do the following :
String className = "A";
Object o= Class.forName(className).newInstance();
But consider this case (simplification):
class Parent {
public void action() {...};
}
class A extends Parent {
#Override
public void action() {...};
}
class B extends Parent {
#Override
public void action() {...};
}
class C extends Parent {
#Override
public void action() {...};
}
Now I would like to create a class that can be either of those 3 cases.
If I use the above code and create an Object, I wouldn't be able to call the action method.
I would like to be able to create an object that extends Parent from a string.
In my actuall case I have multiple different parents, and the class is extented from a class that's extended from a class and about 4 layers of inhertiance. Would regular casting work?
Casting would work, but is unnecessary. Class#newInstance() returns an instance of type T, which is the class' generic type. This means that because Class.forName("A") returns an instance of Class<A>, you can declare your instance as Parent due to A's inheritance, as newInstance() is returning an object of type A.
Parent p = Class.forName("A").newInstance();
p.action();
Since all your classes extend Parent you can cast result of newInstance() to this type and then call all methods declared in Parent. The "right" implementation will run.
Parent p = (Parent)Class.forName(className).newInstance();
p.action();

The meaning of 'subclasses of the containing class' in Java?

I came across the expression 'subclasses of the containing class' when I read a paper. What does that containing class mean in Java? This is the excerpt from the paper.
Primarily, this entailed three things: (i) studying the implementation of the entity, as well as its usage, to reason about the intent behind the functionality; (ii) performing static dependency analysis on the entity, and any other types, methods, or fields referenced by it, including constants; and (iii) examining the inheritance hierarchy and subclasses of the containing class. This approach took considerable time and effort to apply.
This example has a subclass of the containing class:
class Parent {
class Child {
}
}
class ParentSubclass extends Parent {
void whatever() {
new Child(); // Creates an instance of Parent.Child
}
}
ParentSubclass is a subclass of the containing class of Child. Note that outside of Parent (or its subclasses), new Child() will not work, as you need to have a containing ("outer") class to instantiate a non-static "inner" class.
Things get a bit crazy when you now add a method doSomething to Parent, invoke it in Child but override it in ParentSubclass.
class Parent {
void doSomething() {
System.out.println("Not doing anything");
}
class Child {
void whatever() {
doSomething(); // actually: Parent.this.doSomething()
}
}
}
class ParentSubclass extends Parent {
void doSomething() {
System.out.println("I'm just slacking.");
}
void whatever() {
Child a = new Child(); // Creates an instance of Parent.Child
a.whatever(); // will print "I'm just slacking".
}
}
Situations like this make static code analysis a quite hard problem.
Since I have no access to the paper, this is my best guess: in Java, classes can be related to each other in more than one way: in addition to inheriting from one another, classes can also be nested inside one another.
Here is an example of a class inheriting from the class inside which it is nested:
public class Outer {
public void doSomething() {
// ...does something
}
private static class Inner extends Outer {
public void doSomething() {
// ...does something else
}
}
}
In the example above, Inner inherits from Outer, which serves as its containing class.

calling parent class method from child class object in java

I have a parent class which has a method, in the child class I override that parent class's method. In a third class I make an object of child and by using that object I want call the method of parent class. Is it possible to call that parent class method ? If yes, then how?
If you override a parent method in its child, child objects will always use the overridden version. But; you can use the keyword super to call the parent method, inside the body of the child method.
public class PolyTest{
public static void main(String args[]){
new Child().foo();
}
}
class Parent{
public void foo(){
System.out.println("I'm the parent.");
}
}
class Child extends Parent{
#Override
public void foo(){
//super.foo();
System.out.println("I'm the child.");
}
}
This would print:
I'm the child.
Uncomment the commented line and it would print:
I'm the parent.
I'm the child.
You should look for the concept of Polymorphism.
Use the keyword super within the overridden method in the child class to use the parent class method. You can only use the keyword within the overridden method though. The example below will help.
public class Parent {
public int add(int m, int n){
return m+n;
}
}
public class Child extends Parent{
public int add(int m,int n,int o){
return super.add(super.add(m, n),0);
}
}
public class SimpleInheritanceTest {
public static void main(String[] a){
Child child = new Child();
child.add(10, 11);
}
}
The add method in the Child class calls super.add to reuse the addition logic.
First of all, it is a bad design, if you need something like that, it is good idea to refactor, e.g. by renaming the method.
Java allows calling of overriden method using the "super" keyword, but only one level up in the hierarchy, I am not sure, maybe Scala and some other JVM languages support it for any level.
Say the hierarchy is C->B->A with A being the base class.
I think there's more to fixing this than renaming a method. That will work but is that a fix?
One way is to refactor all the functionality common to B and C into D, and let B and C inherit from D: (B,C)->D->A Now the method in B that was hiding A's implementation from C is specific to B and stays there. This allows C to invoke the method in A without any hokery.
NOTE calling parent method via super will only work on parent class,
If your parent is interface, and wants to call the default methods then need to add interfaceName before super like IfscName.super.method();
interface Vehicle {
//Non abstract method
public default void printVehicleTypeName() { //default keyword can be used only in interface.
System.out.println("Vehicle");
}
}
class FordFigo extends FordImpl implements Vehicle, Ford {
#Override
public void printVehicleTypeName() {
System.out.println("Figo");
Vehicle.super.printVehicleTypeName();
}
}
Interface name is needed because same default methods can be available in multiple interface name that this class extends. So explicit call to a method is required.

How to override method to invoke superclass' superclass method? [duplicate]

This question already has answers here:
Closed 13 years ago.
Part of me thinks that this shouldn't be possible (even if it is), but I'll ask anyway.
Given the following class hierarchy (Grandparent and Parent are from a 3rd party and thus, not under my control), how would I override myMethod() in Child such that it bypasses the overridden implementation in Parent and invokes the one in Grandparent?
class Grandparent {
public void myMethod() {
// do stuff
}
}
class Parent extends Grandparent {
#Override public void myMethod() {
super.myMethod();
// do something else
}
}
class Child extends Parent {
#Override public void myMethod() {
// ??? I want to *only* do what Grandparent did here
}
}
Pretend that the Parent class provides a lot of other helpful behavior and is a crucial element of Child's hierarchy (in other words, I'm not looking for "make Child a subclass of Grandparent".
The idea behind inheritance is that each class defines their methods how they need, so you don't need to be inspecting any code.
It seems like you're subclassing here just to re-use code, and that's not the idea of subclassing.
Maybe you should have a helper member to do some of the tasks you need, instead of subclassing, and have both "Child" and "Parent" classes extend "Grandparent".
The main question you need to ask yourself is: "Is Child really a descendant of Parent, Grandparent or neiter?" In other words, for every instance of Child, can I say it's a Parent?
If the answer is no, then you're subclassing wrongly: inheritance is supposed to mean something, not just code re-use (i.e. Ford IS ALSO a Car, not just "Ford" uses "Car" methods).
Assuming that I couldn't touch the code in Parent or Grandparent and assuming that I'm not, as Seb suggested (and as Steve apparently agreed) simply misusing inheritance entirely:
I'd create a local instance of a Grandfather object (or a local class extending Grandfather, if it's abstract) and access its interpretation of myMethod() directly. Of course, depending on how much state information myMethod() is supposed to read and/or manipulate, the amount of work involved could be anything from "easy" to "excruciating".
It's an ugly solution, and, depending on how much state information is accessed, could be brittle as hell. But if Grandfather is reliably stable and/or myMethod() is fairly self-contained, it could work. The devil is in the details, as always.
I definitely agree with Seb that this is re-use, not inheritance. But, hey. Re-use is often a Good Thing.
Not possible.
I would create a final helper method in grandparent instead. And have this method (which is overridden) call that helper.
class Grandparent {
public final void myHelperMethod() {
// do stuff
}
public void myMethod() {
myHelperMethod();
}
}
class Parent extends Grandparent {
#Override public void myMethod() {
super.myMethod();
// do something else
}
}
class Child extends Parent {
#Override public void myMethod() {
// ??? I want to *only* do what Grandparent did here
myHelperMethod();
}
}
Do you have control of the Parent class?
If so, could you add a method (myNewMethod) to the Parent that calls myMethod on Grandparent, and call myNewMethod from Child?
(I'm not a Java person, so don't know if you can only call a method in a superclass from an override of that method in a subclass)
class Grandparent {
public void myMethod() {
myHelperMethod();
}
}
class Parent extends Grandparent {
#Override public void myMethod() {
super.myMethod();
// do something else
}
public final void myNewMethod() {
super.myMethod();
}
}
class Child extends Parent {
#Override public void myMethod() {
// ??? I want to *only* do what Grandparent did here
myNewMethod();
}
}

Categories