2

所以我在一个零碎的文件夹中得到了这段代码,这些代码将用于一个已经停止开发的项目。但是,作为 Java 新手,我有几个问题(我知道代码无法编译,但这适用于我的问题之一)。

interface Executable { 
   public int execute (Object o); 
} 

public class Biv implements Executable { 

   public int execute (String s) { 
     System.out.println (s); 
     return s.length(); 
   } 

   public static void main (String[] args) { 
     Executable e = new Biv(); 
     System.out.println( 
         e.execute ("Hello World!")); 
   }


}

1)我的第一个问题是关于变量 e。它是用 Executable 对象类型声明的,但是我不明白为什么它可以用新的 Biv 对象实例化。这是怎么回事,这是什么意思?

2)错误出现在 Biv 类中的执行方法中。这似乎是因为它需要一个对象而不是字符串。但是,不能因为 String 是 Object 的子类,就不能用 String 替换 Object 吗?我可以理解,如果您将 String 替换为 Object ,它会出现错误(我认为),但不是当前的完成方式。

4

6 回答 6

2

我不明白为什么它可以用新的 Biv 对象实例化

因为Biv实现Executable了,所以任何实例Biv也是 的实例Executable

错误出现在 Biv 类中的执行方法中

是的,它 [ Biv] 没有实现execute(Object). 该方法execute(String)只是碰巧具有相同名称的不同方法,因为它们没有相同的签名。任何实现该接口的类都Executable必须重写该方法execute(Object)

java中重写方法的参数没有变,因为它是不安全的。如果你调用了e.execute(new Object())怎么办?[在哪里e引用Biv对象]Biv将不知道如何处理它。

于 2012-04-08T23:38:07.100 回答
1

1) 变量 e 被声明为 Executable,它是 Biv 实现的接口。这意味着您可以实例化 Biv,但将其存储为 Executable 并将其作为 Executable 传递。该变量现在只能被视为可执行文件。这就是多态性。

2)这是因为您试图覆盖一个函数并为签名添加额外的限制。这违反了 Liskov 替换原则。对于函数,原则基本上是“承诺不少,要求不多”。当接口说它可以是一个对象时,你正在做的是通过强制参数是一个字符串来“要求更多”。然后,将其与 (1) 联系起来,如果 main 中的 Executable 对象调用了它的 execute() 方法,它不应该限制你只向它传递一个 String (因为 Executable 接口说 execute() 可以接受一个 Object )。

于 2012-04-08T23:43:55.297 回答
0

您正在查看的是多态性,它是面向对象程序中的基本概念之一。要回答您的具体问题 #2,您需要匹配接口中方法的类型签名(它需要一个对象作为参数),然后将其转换为字符串。但是,在 Java 中,这种(强制转换)是一种不好的做法,应尽可能避免。

于 2012-04-08T23:37:42.923 回答
0

您没有覆盖方法 from Executable(这是必需的),而是重载了它(相同的名称,不同的参数类型)。

使用@Override注释,这将有助于突出显示错误:

public class Biv implements Executable { 

   @Override // This will cause an error to be highlighted saying this isn't overriding any method
   public int execute (String s) { 
     System.out.println (s); 
     return s.length(); 
   }
}
于 2012-04-08T23:42:02.933 回答
0

Object 类实现了一个 toString() 方法,因此不需要强制转换。更改 Biv 以接收对象而不是字符串,并在方法中首先调用对象的 toString(),然后获取字符串的长度:

interface Executable { 
   public int execute (Object o); 
} 

public class Biv implements Executable { 

   public int execute (Object s) { 
      System.out.println (s); 
      return s.toString().length(); 
   } 

   public static void main (String[] args) { 
      Executable e = new Biv(); 
      System.out.println( 
          e.execute ("Hello World!")); 
   }

}

然而,使用 Object 来实现命令设计模式通常是不好的做法,以便拥有一个接受多种类型可能参数的方法。最好将参数封装在 Parameter 接口后面。

于 2012-04-08T23:50:03.897 回答
0

首先让我们考虑这一行:

public class Biv implements Executable

implements Executable表示该类Biv可以扮演一个Executable. 或者换句话说,Biv实现了Executable.

这解释了为什么稍后您可以这样做:

Executable e = new Biv();

我有一个类型的变量,Executable这次我将使用它的Biv实现。如果Biv实现了该Executable接口(并且它在您的示例中声明了它),那么这没关系。

现在让我们来看看这个例子开始出错的地方。可执行文件中的接口包含此方法声明:

public int execute (Object o);

这就是说,你可以随意调用execute和传入任何Object你喜欢的东西。但是你能把你喜欢的任何对象传递给executein 的方法Biz吗?不,你只能通过一个String. 所以 Biz 并没有完全满足界面。

[圆椭圆问题] 可能是很好的延伸阅读。1

于 2012-04-08T23:53:22.613 回答