关于Java泛型和子类

时间:2014-01-22 15:52:43

标签: java overloading

好的,我从未大量使用过泛型,并且想知道我是否可以通过以下方式使用它们。

假设我有这个课程

public class ASuperClass {
    public abstract void doSomething(String arg1, Integer arg2);
}

所以,如果我然后扩展上面的类,那么我将有以下内容,我将被迫使用String和Integer的参数列表覆盖doSomething。

public class ASubClass extends ASuperClass{
    @Override
    public void doSomething(String arg1, Integer arg2){
        some code.....
    }
}

现在,让我们假设在我的子类中我可以覆盖doSomething,但我的子类中需要一个额外的String arg。所以,我想做的是如下:

public class ASubClass extends ASuperClass{
    @Override
    public void doSomething(String arg1, Integer arg2, String arg3){
        some code...
    }
}

上面的内容不会编译,因为我的子类没有实现基类中定义的抽象签名。所以,要编译它,我当然可以这样做:

public class ASubClass extends ASuperClass{
    @Override
    public void doSomething(String arg1, Integer arg2){}

    public void doSomething(String arg1, Integer areg2, String arg3){
        here is my code......
    }
}

那么,我到底想要做什么,你可能会问?我感兴趣的是,有没有办法使用泛型作为arg“强制”类的任何子类来实现基本的抽象方法,而不管arg列表。以便以下编译扩展ASuperClass:

public class ASubClass extends ASuperClass{
    @Override
    public void doSomething(String arg1, Integer areg2, String arg3){
        here is my code......
    }
}

 public class AnotherSubClass extends ASuperClass{
    @Override
    public void doSomething(String arg1, Integer areg2, String arg3, Integer arg4){
        here is my code......
    }
}

那么,你可以“泛化”基类arg列表,以便上面两个类可以编译吗?像下面的东西?我知道下面的语法是错误的,但你可以使arg列表通用吗?

public class ASuperClass {
    public abstract void doSomething(<?>);
}

总的来说,我的想法是在人们扩展一些基本功能的应用程序中强制实现一致性。基本上要确保ASuperClass的每个子类都有一个doSomething()成员函数,以确保跨子类的一致性(特别是方法命名),但每个子类的arg列表可能不同。

希望以上内容不会太混乱。有兴趣知道这是否可行。

3 个答案:

答案 0 :(得分:0)

public class ASuperClass 
{
    public abstract void doSomething(Object ... args);
}

public class ASubClass extends ASuperClass
{
    @Override
    public void doSomething(Object ... args)
    {
        here is my code......
    }
}  

这将允许两个来电:doSomething(str1, int1)doSomething(str1, int1, str2, int2);

答案 1 :(得分:0)

方法参数是方法“签名”的一部分,用于决定覆盖。为了使子类覆盖其基类中的方法,实现其抽象基类的抽象方法,或实现接口方法,整个签名(包括参数类型)必须匹配。

如果您希望参数列表采用可变数量的参数,则可以使用以下语法:

public abstract void doSomething(Object ... args);

您可以在子类中使用此签名覆盖方法,并且可以根据需要传递任意数量的参数。这个设计决定的一些不幸后果是

  • 您的参数现在是无类型的 - 在继续计算之前,每个方法都需要验证其参数列表,包括其类型,
  • 原始类型的参数需要包含在Object s 中 - 原语需要装箱或自动装箱。

答案 2 :(得分:0)

如果定义这样的抽象方法,则意味着实现此抽象类的任何类型的对象都保证包含此方法。

例如,请查看此代码示例。

List<ASuperClass> list = new ArrayList<ASuperClass>();
list.add(new ASubClass());
list.add(new AnotherSubClass());

因此,我们创建一个所有类型为ASuperClass的对象列表,然后将两个对象添加到此列表中。这些对象具有不同的类型,但它们都共享这个共同的父对象。这意味着我们可以保证它们将响应ASuperClass类型上的所有方法签名。

for(ASuperClass obj : list)
{
  obj.doSomething("parm1", 1);
}

如果你让子类型确定参数列表,那么这会打破这个。我们知道有一个名为doS​​omething的方法,但它对我们没用,因为无法知道参数应该是什么。

正如其他人所说的那样,有一种愚蠢的做法。

public abstract void doSomething(Object ... params);

虽然这是严格正确的,但我确信没有一个心智正常的人会建议这样做。它只被建议完整性。

另一方面,如果您想要相同类型的可变数量的参数,那么您可以更安全地使用它。

public abstract void doSomething(String parm1, Integer parm2, String ... params);

在这种情况下,您将始终需要String,Integer和可变数量的字符串。这真的相当于这样做。

public abstract void doSomething(String parm1, Integer parm2, String[] params);