A method to take a number of types

自古美人都是妖i 提交于 2019-12-11 06:58:44

问题


I currently am working with a constructor which takes in of type object I am then testing it's type based on instanceof

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();
}
}

Can this be offset to an initalise method called from within the constructor. The major problem is in the casting of the Object. I was always under the impression that repeated code is bad code. Can this be made more elegant?


回答1:


A much better, more type-safe design would be to create multiple overloaded constructors. You would then not need any casts, and you would make it impossible to construct 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 consider creating an interface that both these classes implement, and create a constructor that takes an object that implements that 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();
    }
}



回答2:


Create one method for each type of the object instead.

public MyClass(CusClass1 obj) {
    field1 = obj.getProperty1();
    field2 = obj.getProperty2();
}

public MyClass(CusClass2 obj) {
    field1 = obj.getOtherProperty1();
    field2 = obj.getOtherProperty2();
}



回答3:


Do not repeat code and do not cast. Create 2 constructors: one accepts CusClass1, second CusClass2. Implement them separately.




回答4:


If you can modify CusClass1 and CusClass2, you could create an interface

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

and then ensure that CusClass1 and CusClass2 implement this interface:

 public class CusClass1 implements AttributeProvider {
     ...
 }

then you can have a constructor with just that interface:

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

That way, you won't have to modify MyClass if you create a new CusClass3 which should also be used in MyClass




回答5:


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

Otherwise, yes, you can use and init method like this:

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();
    }
}



回答6:


If you have many such custom classes, it may 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 the custom classes have the necessary attributes/methods with the same names (like attrib1 and attrib2 in your example), reflection is the easier. All you need is a set of potential class names, and the names of the attributes to query.

If, however, the attribute names may vary, you may consider using annotations to mark the desired source attributes in each class.



来源:https://stackoverflow.com/questions/7189132/a-method-to-take-a-number-of-types

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!