java重载方法
我有一个抽象模板方法:java重载方法,java,Java,我有一个抽象模板方法: class abstract MyTemplate { public void something(Object obj) { doSomething(obj) } protected void doSomething(Object obj); } class MyImpl extends MyTemplate { protected void doSomething(Object obj) {
class abstract MyTemplate
{
public void something(Object obj)
{
doSomething(obj)
}
protected void doSomething(Object obj);
}
class MyImpl extends MyTemplate
{
protected void doSomething(Object obj)
{
System.out.println("i am dealing with generic object");
}
protected void doSomething(String str)
{
System.out.println("I am dealing with string");
}
}
public static void main(String[] args)
{
MyImpl impl = new MyImpl();
impl.something("abc"); // --> this return "i am dealing with generic object"
}
如何在doSomething(objectobj)中使用instanceof打印“我正在处理字符串”
谢谢,这是不可能的。MyImpl中的doSomething(Object obj)是重写MyTemplate中的doSomething的方法
在MyImpl中的doSomething(Object obj)中使用instanceof操作符。无论如何,这是一种更好的风格。你真的做不到。Java不能进行开箱即用的双重分派。问题是方法调用的绑定通常在编译时完成 这里 这里呢
简而言之,你不能。其他答案解释了原因。另一种方法可能是使用泛型,并依赖抽象类的特定子类型来处理字符串(或其他特定类)。例如:
abstract public class MyTemplate<T> {
abstract public void doSomething(T t);
}
public class MyTemplateImpl extends MyTemplate<Object> {
@Override
public void doSomething(Object o) {
System.out.println("Dealing with a generic Object");
}
}
public class MyTemplateImplForStrings extends MyTemplate<String> {
@Override
public void doSomething(String s) {
System.out.println("dealing with a String");
}
}
或
MyTemplate template=新的MyTemplateImplforString();
模板。doSomething(“你好”)//打印“处理字符串”
注意:除非您也使用字符串参数化抽象基,否则您将避免使用抽象基作为引用类型;否则您将在运行时为ClassCastException敞开大门,编译器应该警告您这一点。java编译器使用方法参数的编译时类型来创建方法调用,在我们的示例是对象而不是字符串。参数的运行时类型被方法调用忽略
如果您控制所有输入类或使用,您可以尝试使用,这很慢/复杂且容易出错。从OO的角度来看,我会仔细思考,为什么我需要这样的构造。类对象的实例没有太多行为,为什么要将它们作为参数传递?Horst也这么说。如果您要将基类定义为在方法签名中使用类型“Object”,你真的不应该假设处理特定类型。我建议用泛型来定义MyTemplate的类层次结构。我认为instanceof的使用通常暗示可能违反Liskov替换原则(LSP)。在这种情况下,子类似乎是“优化的”“对于一种特殊类型的对象,尽管它能够处理所有对象。因此,我们需要一些区分,这是由instanceof完成的。而且我也不喜欢这个原则,因为子类化某些东西并使用代替原始对象是修改程序的好方法。也许我只是不明白原理。对于这类事情,多态性应该比instanceof更受青睐。此外,如果您正在检查(并可能强制转换为)方法中的特定子类型,那么您的方法应该接受子类型作为参数,而不是超类型(在OP提供的示例中,可以通过泛型实现)。
MyTemplateImplForStrings template = new MyTemplateImplForStrings();
template.doSomething("hello"); //prints ""dealing with a String"
MyTemplate<String> template = new MyTemplateImplForStrings();
template.doSomething("hello"); //prints ""dealing with a String"