Java接口方法

Java接口方法,java,methods,interface,implements,Java,Methods,Interface,Implements,只是在玩界面,我有一个问题,我不能真正理解 以下代码不运行,这是我所期望的行为,因为接口方法要求该方法对任何对象都有效,而实现的方法将签名更改为仅允许字符串对象。 interface I { public void doSomething(Object x); } class MyType implements I { public void doSomething(String x) { System.out.println(x); } } 然而,使

只是在玩界面,我有一个问题,我不能真正理解

以下代码不运行,这是我所期望的行为,因为接口方法要求该方法对任何对象都有效,而实现的方法将签名更改为仅允许字符串对象。

interface I {
    public void doSomething(Object x);
}

class MyType implements I {
    public void doSomething(String x) {
        System.out.println(x);
    }
}
然而,使用下面的代码块,我震惊地发现它确实有效我认为它不会工作,因为我们希望返回一个对象,而实现的方法将只返回一个字符串对象。为什么这样做?这里传递的参数和返回类型的两个原则有什么区别?

interface I {
    public Object doSomething(String x);
}

class MyType implements I {
    public String doSomething(String x) {
        System.out.println(x);
        return(x); 
    }
}

它之所以能工作,是因为
字符串
是java语言规范中的
对象

如果返回类型是引用类型,则相互重写的方法之间的返回类型可能会有所不同。返回类型可替换性的概念支持协变返回,即返回类型对子类型的专门化


换句话说,它的工作原理与您的相同,但如果接口中的返回类型为String,而实现类中的返回类型为Object,则它将不起作用。

第一个示例不起作用,第二个示例起作用的原因是,函数原型仅由名称和所有参数定义,而不是由返回类型定义。在第一个示例中,存在差异,因此编译器认为它们是两个不同的函数

在第二个示例中,实现的函数没有扩展类型,而是专门化类型(字符串是对象的专门化),因此它可以工作

同样,您可以限制实现方法的可见性,但不能扩展它

此外,Java有泛型,在这种上下文中很有用

例如:

interface I<T>
{
    public void doSomething(T x);
}

class MyType implements I<String>
{
    public void doSomething(String x)
    {
        System.out.println(x);
    }
}
接口I
{
公共无效剂量测定(tx);
}
类MyType实现了I
{
公共无效剂量测定(字符串x)
{
系统输出println(x);
}
}

方法签名不考虑返回类型。(尽管声明两个具有相同签名但返回类型不同的方法是错误的)。因此:

只是两个方法,没有一个方法重写或实现另一个

public Object doSomething(String x);
必须归还一些东西。任何东西,事实上,只要它是某种类型的对象。所以如果你实施

public String doSomething(String x) {stuff}
这很好,因为它实际上返回了一个对象。它将返回的对象始终是字符串这一事实并没有什么大不了的

第一个示例不起作用的原因是,只接受字符串比接受任何对象更具限制性。但是只返回字符串是可以的


打个比方,假设你有一份粉刷大楼的合同,你会雇佣一些员工来帮助你。合同要求你雇佣任何合适的油漆工,不管他们有多高,但没有指定使用什么颜色的油漆。如果你只雇佣超过6英尺高的画家(这是输入,只接受字符串而不是所有对象),你就违反了合同。但是选择只使用蓝色油漆(只返回字符串)也没问题,因为合同没有规定颜色,只是要求你必须粉刷建筑物。

这种行为背后的原则被称为。在这种特殊情况下,overriding类型可能会“缩小”最初声明的参数类型


这意味着,由于
String
Object
的子类,
Object
可以被
String

字符串类继承自Object类,因此只有此代码有效

这与Java SE 5.0中引入的协变返回类型有关

你可以在

中看到更多细节,但这并不是真正的答案。他的第一个例子也有同样的“演员阵容”。第二次成功的原因由maressThere解释。在他的第一个例子中没有演员。接口声明一个将对象作为参数的方法。拥有一个接受字符串的方法与接受对象不同。你能把一个整数传递给他的string方法吗,就像你能传递给一个接受对象的方法一样?这更像是一个答案,但仍然不是很清楚:p
public String doSomething(String x) {stuff}