使用Java中的类型推断和泛型方法

时间:2017-08-07 15:30:40

标签: java generics

我有一个课程src.at<unsigned short>(i) = input_image[i]/1024*65536; 和两个课程src.at<unsigned short>(i) = input_image[i]*64; Person延伸Male

Female

Person中,有一个字段public class Male extends Person{ [...] } 可以区分子类,但也可以使用Person

我有一个方法sex可以返回PersonfooPerson类型的对象。是否应使用通用方法实现返回类型?

类似的东西:

Male

那么我应该如何声明类Female和子类?

如果我不知道如何实例化对象,我该如何使用该方法?

public <T> foo(Sex sex) {
    if (sex=Sex.M)
        return new Male();
    else if (sex=Sex.F)
        return new Female();
    else
        return new Person();
}

编辑:

这样做的:

Person

public static void main(String[] args){ ??? test = foo(Sex.M); //working on test } 中我可以使用public Person foo(Sex sex) { if (sex=Sex.M) return new Male(); else if (sex=Sex.F) return new Female(); else return new Person(); } main中声明的方法,即使它们是在子类中声明的吗?因为Male属于Female类型。

4 个答案:

答案 0 :(得分:3)

每个孩子都是父母。

只需将您的声明public <T> foo(Sex sex) {更改为

即可

public Person foo(Sex sex) {

然后再次测试你可以做到

  Person test = foo(sex);

请注意,由于您不知道从foo方法接收哪个Child,因此如果操作特定于Child,则需要在对其进行操作之前进行检查。

编辑:

  

在main中,我可以使用在Male或Female中声明的方法,即使它们是在子类中声明的吗?因为测试属于Person类型。

这就是我作为笔记添加的内容。你不能直接使用。您只能使用常见的东西(来自父项的变量和方法)。如果您想要从Child执行某些特定调用,则需要将test投射到该特定Child类型。

像这样的东西

public static void main(String[] args){
    Person test = foo(sex);
   if(test instanceof Male) {
     Male m = (Male) test;
     // use m as male
   }
}

为什么我使用test instanceof Male只是为了在其他类型的情况下保存我自己失败。

答案 1 :(得分:1)

此处您不需要generics。这里Person是男性和女性的superclass。 因此,在需要的地方使用Person声明。稍后它总是可以容纳子类实例。

以下情况将在所有情况下都没问题 -

public Person foo(Sex sex) {
    if (sex="m")
        return new Male();
    else if (sex="f")
        return new Female();
    else
        return new Person();
}

这是因为以下所有分配都是正确的。

Person a;
a = new Person(); //correct 
a = new Male(); //correct
a = new Female(); //correct

答案 2 :(得分:0)

您正在利用继承,并且不需要混合泛型。您可以简单地将Person定义为返回类型 - 您将能够返回MaleFemale个实例因为那些也是Person

public Person foo(Sex sex) { ... }

然后一切都变得清晰:

Person test = foo(sex);

答案 3 :(得分:0)

首先,我认为Person类不应该是可实例化的。是否有任何用例需要创建Person类型的对象而不是Male类型Female的对象?

Person作为具体类,您尝试使用代码重用,这在面向对象编程中是不好的做法。

  

首选组合而不是继承

他们说。

无论如何,使用您的解决方案还有另一个问题:您可能有抽象泄漏。超类不应该知道可用的子类的可能类型。如果方法foo位于Person类中,则会遇到此问题。

最后,仿制药不会帮助你。您需要检查您的设计。正如您对问题的评论中所建议的那样,一个可能的优雅解决方案应该如下:

abstract class Person {
    // Omissis
    public abstract String sex();
    // Omissis
}

class Male {
    // Omissis
    public String sex() {
        return "M";
    }
    // Omissis
    public static Male of() {
        return new Male();
    }
}

class Female {
    // Omissis
    public String sex() {
        return "M";
    }
    // Omissis
    public static Femaleof() {
        return new Female();
    }
}

因此,如果您需要一种方法来创建新的男性或女性,您可以拥有一个专用类型,一个工厂,如下所示:

class PersonFactory {
    public Person build(String sex) {
        if ("M".equals(sex) return new Male();
        else return new Female();
    }
    public Male male() {
        return new Male();
    }
    public Female female() {
        return new Female();
    }
}

您可以使用直接在两个子类中定义的Male方法Female,而不是构建staticof的专用类型。这将关闭(SOLID)你的设计与新类型的人的添加。

显然,男性或女性的所有行为也应该适用于某个人,这意味着您可能需要在abstract课程中使用更多Person方法。

干杯。