[英]About Java generics and subclasses
好的,我从来没有大量使用过泛型,并且想知道是否可以通过以下方式使用它们。
假设我有这堂课
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列表可能有所不同。
希望以上内容不会太混乱。 有兴趣知道这是否可能。
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);
方法参数是方法“签名”的一部分,用于决定覆盖。 为了使子类重写其基类中的方法,实现其抽象基类的抽象方法或实现接口方法,整个签名(包括参数类型)必须匹配。
如果您希望参数列表采用可变数量的参数,则可以使用以下语法:
public abstract void doSomething(Object ... args);
您可以在子类中使用此签名覆盖方法,并且可以根据需要传递任意数量的参数。 此设计决定的一些不幸后果是:
Object
- 基本类型需要装箱或自动装箱。 如果定义这样的抽象方法,则意味着实现该抽象类的任何类型的对象都可以保证包含该方法。
例如,看下面的代码示例。
List<ASuperClass> list = new ArrayList<ASuperClass>();
list.add(new ASubClass());
list.add(new AnotherSubClass());
因此,我们创建了所有类型均为ASuperClass的对象列表,然后将两个对象添加到该列表中。 这些对象具有不同的类型,但是它们都共享此公共父对象。 这意味着我们可以保证它们将响应ASuperClass类型上的所有方法签名。
for(ASuperClass obj : list)
{
obj.doSomething("parm1", 1);
}
如果让子类型确定参数列表,则可能会破坏此列表。 我们会知道有一种叫做doSomething的方法,但是对我们来说这是没有用的,因为无法知道参数应该是什么。
正如其他人所建议的那样,这样做有很简单的方法。
public abstract void doSomething(Object ... params);
虽然这是完全正确的,但我敢肯定,在他们的正确思想中没有人会建议这样做。 仅出于完整性的目的提出了此建议。
另一方面,如果您想要可变数量的相同类型的参数,则可以更安全地使用它。
public abstract void doSomething(String parm1, Integer parm2, String ... params);
在这种情况下,您将始终需要一个字符串,一个整数,然后是可变数量的字符串。 这实际上等同于执行此操作。
public abstract void doSomething(String parm1, Integer parm2, String[] params);
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.