Java 类继承和转换

Java 类继承和转换,java,inheritance,object,methods,casting,Java,Inheritance,Object,Methods,Casting,因此,我在一个文件夹中收到了这段代码,其中包含了一些零碎的东西,这些零碎的东西将用于一个后来停止开发的项目。然而,作为Java新手,我有几个问题(我知道代码没有编译,但这是我的一个问题) 1)我的第一个问题是关于变量e。它是用可执行对象类型声明的,但是我不明白为什么可以用新的Biv对象实例化它。这里发生了什么,这意味着什么 2)错误在Biv类中的execute方法中。这似乎是因为它需要对象而不是字符串。但是,不能用字符串替换对象,因为字符串是对象的子类?我可以理解,如果用对象替换字符串,它会有一

因此,我在一个文件夹中收到了这段代码,其中包含了一些零碎的东西,这些零碎的东西将用于一个后来停止开发的项目。然而,作为Java新手,我有几个问题(我知道代码没有编译,但这是我的一个问题)

1)我的第一个问题是关于变量e。它是用可执行对象类型声明的,但是我不明白为什么可以用新的Biv对象实例化它。这里发生了什么,这意味着什么

2)错误在Biv类中的execute方法中。这似乎是因为它需要对象而不是字符串。但是,不能用字符串替换对象,因为字符串是对象的子类?我可以理解,如果用对象替换字符串,它会有一个错误(我认为),但不是它当前的操作方式。

您所看到的是,面向对象程序中的一个基本概念。要回答特定的问题#2,您需要匹配接口中方法的类型签名(它将对象作为参数),然后将其转换为字符串。但是,在Java中,这种(强制转换)是一种错误,应该尽可能避免

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

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

错误在Biv类中的execute方法中

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

java中没有用于重写方法的参数,因为这样做不安全。如果调用
e.execute(newobject())
,会怎么样?[当
e
引用
Biv
对象时,
Biv
将不知道如何处理它。

您不是在从
可执行文件
重写方法(这是必需的),而是在重载它(相同的名称,不同的参数类型)

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

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(); 
   }
}
1) 变量e被声明为可执行文件,它是Biv实现的接口。这意味着您可以实例化Biv,但将其存储为可执行文件并作为可执行文件传递。该变量现在只能作为可执行文件处理。这是多态性


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

对象类实现了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!")); 
   }

}

然而,通常不好的做法是使用对象实现命令设计模式,以获得一种接受多种类型的可能参数的方法。最好在参数接口后面封装参数。

首先让我们考虑这一行:

public类Biv实现可执行文件

实现可执行文件
表示类
Biv
可以担任
可执行文件
的角色。或者换句话说,
Biv
实现了
可执行文件中的所有方法

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

可执行文件e=new Biv()

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

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

public int-execute(对象o)

也就是说,您可以调用
execute
并传入您喜欢的任何
对象。但是您可以将任何您喜欢的对象传递给
Biz
中的
execute
方法吗?不可以,您只能传递
字符串
。所以Biz并没有完全满足界面的要求


[圆-椭圆问题]可能值得进一步阅读。

值得注意的是,签名不一定必须完全相同;参数类型可能是“松散的”。例如,如果接口中的方法采用
字符串
,则可以在
Biv
中采用
对象
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!")); 
   }

}