A method of accepting several types

I am currently working with a constructor that accepts an object of type Then I test it based on the instance

Public MyClass (Object obj) { if(obj instanceof CusClass1){ CusClass1 myObject = (CusClass1) obj; globalVar1 = myObject.getAttrib1(); globaVar2 = myObject.getAttrib2(); } if(obj instanceof CusClass2){ CusClass2 myObject = (CusClass2) obj; globalVar1 = myObject.getAttrib1(); globaVar2 = myObject.getAttrib2(); } } 

Whether this can be biased into the initalise method called inside the constructor. The main problem is casting an object. It always seemed to me that re-code is bad code. Could it be more elegant?

+1
source share
6 answers

A much better, safer type of construction would be the creation of several overloaded constructors. Then you would not need any throws, and you would have made it impossible to create an object by passing it an object of an inappropriate type.

 public MyClass(CusClass1 myObject) { globalVar1 = myObject.getAttrib1(); globalVar2 = myObject.getAttrib2(); } public MyClass(CusClass2 myObject) { globalVar1 = myObject.getAttrib1(); globalVar2 = myObject.getAttrib2(); } 

Do CusClass1 and CusClass2 have the same getAttrib1() and getAttrib2() methods? Then think about creating an interface that these two classes implement, and create a constructor that accepts an object that implements this interface:

 public interface Attribs { String getAttrib1(); int getAttrib2(); } public class CusClass1 implements Attribs { // ... } public class CusClass2 implements Attribs { // ... } public class MyClass { // You can now pass anything that implements interface Attribs public MyClass(Attribs myObject) { globalVar1 = myObject.getAttrib1(); globalVar2 = myObject.getAttrib2(); } } 
+4
source

Create one method for each type of object.

 public MyClass(CusClass1 obj) { field1 = obj.getProperty1(); field2 = obj.getProperty2(); } public MyClass(CusClass2 obj) { field1 = obj.getOtherProperty1(); field2 = obj.getOtherProperty2(); } 
0
source

Do not repeat the code or execute it. Create 2 constructors: one accepts CusClass1, the second CusClass2. Implement them separately.

0
source

If you have many such custom classes, it might be better to use reflection and / or annotations (and especially if not all of them are known at compile time, this may be the only solution).

If all user classes have the necessary attributes / methods with the same names (e.g. attrib1 and attrib2 in your example), reflection is simpler. All you need is a set of potential class names and attribute names for the query.

If, however, the attribute names may differ, you can use annotations to mark the desired source attributes in each class.

0
source

If you can change CusClass1 and CusClass2 , you can create an interface

  public interface AttributeProvider { Object getAttrib1(); // or whatever type getAttrib1 should return Object getAttrib2(); } 

and then make sure that CusClass1 and CusClass2 implement this interface:

  public class CusClass1 implements AttributeProvider { ... } 

then you can have a constructor with this interface:

  public MyClass(AttributeProvider myObject) { globalVar1 = myObject.getAttrib1(); globaVar2 = myObject.getAttrib2(); } 

This way you will not need to modify MyClass if you create a new CusClass3 , which should also be used in MyClass

0
source

If your constructor can be modified to accept CusClass1 and CusClass2 rather than Object, you can follow one of the solutions provided in the other answers.

Otherwise, yes, you can use the init method as follows:

 public class MyClass { public MyClass (Object obj) { if (obj instance of CusClass1) { init((CusClass1) obj); } else if (obj instanceof CucClass2) { init((CusClass2) obj); } // shared initialization code } public void init(CusClass1 obj) { globalVar1 = obj.getAttrib1(); globaVar2 = obj.getAttrib2(); } public void init(CusClass2 obj) { globalVar1 = obj.getAttrib1(); globaVar2 = obj.getAttrib2(); } } 
0
source

Source: https://habr.com/ru/post/952500/


All Articles