不相关对象的通用方法 - java

时间:2014-07-31 14:27:55

标签: java generics

我有两节课:

public Class A{
    String name;
    Integer age;

    //setters and getters
}

public Class B{
    String name;
    Integer age;
    Integer height;

    //setters and getters
}

以及以下方法

public String getMyName(B b){
    return b.getName()+" "+b.getAge()+" "+b.getHeight();
}

是否有可能重构此方法以使用泛型,这将允许我为这两个不同类的对象调用它?

E.g

public <T> String getMyName(T t){
    return t.getName()+" "+t.getAge()+( t instanceof B ? " "+t.getHeight() : "");
}

当然,由于t知道方法getNamegetAgegetHeight,因此无效。

类没有任何关系(我知道它们可以从一个公共类继承并使用<T extends C>但它们没有超类或公共接口)

4 个答案:

答案 0 :(得分:10)

不,如果不使用通用接口或超类,这对于泛型来说是不可能的。您可以使用反射,但我建议反对,并建议提供一个通用界面。

正如其他人所说,还有其他方法可以处理这种情况(例如方法重载或传递Object并使用instanceof和强制转换)但是如果你可以使用通用接口,我会&#39; d仍然那样。

请注意,Java泛型是unlinke C ++泛型/模板,它们可以提供您想要做的事情 - 并且有很好的理由可以解决这个问题。

答案 1 :(得分:2)

这是人们喊Programming with interfaces行的地方。

获取一个接口并为其添加常用方法,并创建一个将该接口作为参数的泛型方法。

这让你的生活变得轻松。

答案 2 :(得分:1)

您可以使用instanceof检查是否为兼容类型,如果是,则将对象强制转换为您的类型并调用方法。这不是优雅的方式,但仍然。这样,您可以将您的方法用作通用方法。 :)

答案 3 :(得分:1)

您可以动态地动态调整它们 - 例如:

public class A {

    String name;
    Integer age;

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }
}

public class B {

    String name;
    Integer age;
    Integer height;

    public String getName() {
        return name;
    }

    public Integer getAge() {
        return age;
    }

    public Integer getHeight() {
        return height;
    }
}

// Create a common interface.
public interface AorB {

    public String getName();

    public Integer getAge();

    // Use Java 8 to implant a default getHeight if it is missing.
    default Integer getHeight() {
        return 0;
    }
}

// Dynamicaly adapt each type.
public String getMyName(A a) {
    // Adapt it on the fly.
    return getMyName(new AorB() {

        @Override
        public String getName() {
            return a.getName();
        }

        @Override
        public Integer getAge() {
            return a.getAge();
        }

    });
}

public String getMyName(B b) {
    // Adapt it on the fly.
    return getMyName(new AorB() {

        @Override
        public String getName() {
            return b.getName();
        }

        @Override
        public Integer getAge() {
            return b.getAge();
        }

        @Override
        public Integer getHeight() {
            return b.getHeight();
        }

    });
}

// Your method almost untouched.
public String getMyName(AorB ab) {
    return ab.getName() + " " + ab.getAge() + " " + ab.getHeight();
}

public void test() {
    A a = new A();
    a.name = "A";
    a.age = 10;

    B b = new B();
    b.name = "B";
    b.age = 10;
    b.height = 12;

    System.out.println("A:" + getMyName(a));
    System.out.println("B:" + getMyName(b));
}

我在这里使用Java-8 default来实现默认的getHeight但是消除它不需要太多努力 - 你需要为{{getHeight实现getMyName(A) 1}}方法。

可悲 - 当然 - 这不是在解决方案中使用泛型,因此您可能会将此视为不是您的问题的答案,但它是替代解决方案的问题所以我选择发帖。