Check if the calling object is an instance of a child class

I have 2 classes. Let them be called class A and class B. Class A contains a method that performs an action. Class B overrides this method with its own version, but makes a super call on this method in class A to complete the action. Now it works fine. However, in class A there are some actions that should be performed only if the object is only an instance of class A. In another way, some actions in the method of class A should not be performed if the object is an instance of a child of class A.

I am currently using instanceof to check each child, but I need to specify each child class, so if a new child is added later, this method needs to be updated. I would like a dynamic way to determine if an object is a child.

Are there any good alternatives or is there instanceof way?

 public class A{ public void someMethod(){ // Only perform these actions if it is not a child class. This is what // I am looking for a better solution for if(!(this instanceof B)){ // Some action... } // Actions to execute for every call } } public class B extends A{ @Override public void someMethod(){ super.someMethod(); // More actions } } 

As an explanation of the design, I use it to create XML. In the program, I have a List<A> for storing data. When it's time to output the XML, I go through the list and call generateXML ( someMethod takes its place in my example).

When an object of class A is created, it must have its data in the <A></A> tags. When an object of class B is created, it must have its data in the <B></B> tags. But all properties of A must also be inside <B></B> tags, so right now it calls the same generateXML method that is used when an object has only class A

But, as some others have pointed out, calling the same method is not the way to go. Class B must invoke a protected method in class A that generates only the necessary information.

+4
source share
8 answers

Create protected methods that do things specific to the class and call them from someMethod (). Class A will provide its implementation, and if the subclass is to effectively remove this code, it can override the protected method with an empty implementation.

Do not fight polymorphism; use it to your advantage.

Example:

 public class A { protected void someOtherMethod() { // Do stuff specific to A here. } public void someMethod() { // Do some stuff someOtherMethod(); // Do some more stuff } } public class B extends A { @Override protected void someOtherMethod() { // Empty implementation; B doesn't need to do this. // Or do stuff specific to B... } } 
+7
source

Well, now that the terrible design has to be solved differently (for example, to make the part called from the subclass with its own protected method), but, alas, if you really need it, you can check

this.getClass () == A.class to make sure the class is really identical.

+3
source

I see instanceof as an opportunity to use polymorphism.

Saving behavior in someMethod for all types A Subclass A , to implement the behavior you are currently checking with instanecof .

 public class A{ public void someMethod(){ // Get rid of the special section and put it in it own class // Keep only agnostic behavior common to all types of A // Actions to execute for every call } } public class B extends A{ @Override public void someMethod(){ super.someMethod(); // More actions } } public class C extends A{ @Override public void someMethod(){ super.someMethod(); // Actions that were originally in the if(instanceof) check } } 
+1
source

Why not:

 public class A{ public void someMethod(){ // Only perform these actions if it is not a child class. This is what // I am looking for a better solution for if(this.getClass().equals(A.class)) // Some action... } // Actions to execute for every call } } 

and

 public class B extends A{ @Override public void someMethod(){ super.someMethod(); // More actions } } 
+1
source

It may be the same as cdhowie was trying to say. (No offense: I thought you were a little obscure.)

Do not use instanceof. Instead, create methods that return flags or other appropriate values ​​for the type.

Your example does not give any details about what you are trying to do, so I’ll just come up with something.

!!! Wrong.

 public class Car { public void goUphill() { // XYZ has automatic transmission -- don't need to downshift if (!(this instanceof XYZ()) { downshift(); } pressGas(); } } public class ModelXYZCar extends Car { public void goUphill() { tellWifeToGetOutAndPush(); super.goUphill(); } } 

The best way:

 public class Car { public boolean isManualTransmission() { // default return true; } public void goUphill() { if (isManualTransmission()) { downshift(); } pressGas(); } } public class ModelXYZCar extends Car { public boolean isManualTransmission() { return false; } public void goUphill() { tellWifeToGetOutAndPush(); super.goUphill(); } } 

Thus, the superclass does not need to know what is needed for subclasses. Each subclass defines its own behavior. In this case, each subclass defines an isManualTransmission function and returns true or false, respectively.

It’s better to avoid the need for checkboxes and put the appropriate behavior in each class:

 abstract public class Car { abstract public void downshift(); public void goUphill() { downshift(); pressGas(); } } public class AutomaticTransmissionCar extends Car { public void downshift() { // Automatic transmission -- no need to do anything } } public class ManualTransmissionCar extends Car { public void downshift() { ... whatever ... } } public class ModelXYZCar extends ManualTransmissionCar { public void goUphill() { tellWifeToGetOutAndPush(); super.goUphill(); } } 
+1
source

The expression A.class.equals(this.getClass()) returns true only if it is truly an instance of class A. If it is a child instance, the result will be false.

BUT: if you need to do this, check your design. It doesn't sound like an object oriented style. I can give you an alternative. Divide your base class A by 2: the truly base class A0 and its child A1. Your class B will be the brother of A1 and will be distributed directly from A0.

In this case, you can put the general code in the class A0 and all the specific code (which in your version should be executed only if the class is exactly A, and not its subclass) to A1.

0
source

I could be wrong, but your case seems like the perfect scenario for "supporting composition over inheritance" and "encapsulating what is changing." One general course of action in a situation like yours:

  • Do not subclass your superclass
  • Isolate a section of code that should belong only to A in a private method.
  • Create an instance of A in B, C, etc. and call A.someMethod ().

     public class A { public void someMethod(){} private void someOtherMethod(){ // move behavior specific to A in here. } } public class B { // no extends public void someMethod() { new A().someMethod(); } } 

Again, I may be wrong, and this may not be relevant to your case.

0
source

"call super" is an anti-pattern . Instead of expecting the subclass to invoke the functionality of the superclass, rotate it the other way around. Now the superclass has full control over what is called both before and after the β€œcommon” material.

 public class A { public void someMethod() { beforeCommonStuff(); // Actions to execute for every call afterCommonStuff(); } protected void beforeCommonStuff() { // Actions to execute only for class A } protected void afterCommonStuff() {} } public class B extends A { @Override protected void afterCommonStuff(){ // More actions } } 
0
source

All Articles