Java:接口

Java:接口,java,class,interface,casting,Java,Class,Interface,Casting,我一直在读java中的接口。总的来说,除了一个问题,我理解这个概念。在(docs.oracle)中,注释中写道我们可以输入cast接口和实现它的类。就是 public interface Relatable { public int isLargerThan (Relatable other) ; } public class RectanglePlus implements Relatable { public int width = 0; public i

我一直在读java中的接口。总的来说,除了一个问题,我理解这个概念。在(docs.oracle)中,注释中写道我们可以输入cast接口和实现它的类。就是

public interface Relatable { 
    public int isLargerThan (Relatable other) ; 
} 

public class RectanglePlus implements Relatable { 
    public int width = 0; 
    public int height = 0; 
    public Point origin; 

    // four constructors 
    // ...

    // a method for computing the area of the rectangle 
    public int getArea() { 
        return width * height; 
    } 

    // a method required to implement the Relatable interface 
    public int isLargerThan(Relatable other) { 
        RectanglePlus otherRect = (RectanglePlus) other; 

        if (this.getArea() < otherRect.getArea()) { 
            return -1; 
        } else if (this.getArea () > otherRect.getArea()) { 
            return 1; 
        } else {
            return 0;
        }
    } 
}
公共接口相关{
公共国际岛国(相关其他);
} 
公共类RectanglePlus实现了相关{
公共整数宽度=0;
公共整数高度=0;
公共点源;
//四个建设者
// ...
//矩形面积的一种计算方法
public int getArea(){
返回宽度*高度;
} 
//实现相关接口所需的方法
公共int isLargerThan(相关其他){
矩形加其他矩形=(矩形加)其他;
如果(this.getArea()otherRect.getArea()){
返回1;
}否则{
返回0;
}
} 
}

如何将otherRect(它是一个接口)转换为矩形Plus。混淆之处在于,RectanglePlus是一个具有变量的类,而另一个Rect是一个接口,

您的接口非常类似,(您确定Compariable不是您想要的吗?),因此您可能应该为其添加一个泛型:

public interface Relatable<T extends Relatable> {

    public int isLargerThan(T t);
}
或者,第三个选项,您可以向接口添加另一个方法,以获得对象的可测量、可实现的值。然后,如果您使用的是Java 8,则可以向isLargerThan添加默认实现:

public interface Relatable<T extends Relatable> {

    public default int isLargerThan(T t) {
        return this.getRelatableValue - t.getRelatableValue();
    }

    public int getRelatableValue();

}
公共接口相关{
公共默认值int isLargerThan(T){
返回this.getRelatableValue-t.getRelatableValue();
}
public int getRelatableValue();
}

在方法声明
public int isLargerThan(Relatable other){…}
中,参数
other
被声明为对其类实现接口
Relatable
的对象的引用


在方法体中,表达式
(RectanglePlus)other
表示检查对象是否属于类
RectanglePlus
或其子类(如果不是,则抛出ClassCastException)。现在,
RectanglePlus
相关的
,但反过来不一定正确;此处的强制转换确保
其他
将为
矩形加上
;如果不是,则不会执行进一步的指令,因为将引发异常。

如果T2是C类的超类或超接口,或者T2==C,则可以将存储在T1类型变量(接口或类)中的任何对象(类C)类型强制转换为T2类型变量,否则将引发ClassCastException


因此,在您的情况下,如果类Foo实现Relatable的对象obj被传递给isLargerThan方法,那么它将抛出ClassCastException,因为obj的classFoo不是RectanglePlus的超类,其他答案中没有涉及到的一个方面是,Oracle文档中的示例有一个明显的问题:如果
Relatable
仅意味着与
compariable
类似,然后需要对形状进行专门化,以避免在
isLargerThan
方法中进行强制转换。例如,可能有一个名为
RelatableShape
的接口,它本身扩展了
Relatable
,并提供了
getArea()
方法。然后,您可以有
六边形
矩形
,等等。实现
相关形状
(与
isLargerThan
getArea
的接口)的类,以及
isLargerThan()
方法不需要将其参数强制转换为特定的具体类(因为可以保证参数实现
RelatableShape
,并且
getArea()
始终可用)


因此,尽管Oracle文档显示了一些有效的Java,但它也显示了一些由于设计不好而必需的东西。请记住,在实际代码中几乎不需要强制转换。

您的方法相当简单

public int isLargerThan(Relatable other)
只要求一个实现Relatable的参数。它可以是任何实现Relatable的类的对象。只要

public class SomeName implements Relatable { /* Implementation */ }
在类中,可以将该类的对象视为可关联的

但这并不意味着这些对象不是它们自己的类型

public class Square implements Relatable {
  public int isLargerThan(Relatable other) {
    // Implementation
  }

  // Square specific implementation
}

您可以像这样调用接口方法:

/* ... */

public static int check(Relatable a, Relatable b) {
  return a.isLargerThan(b);
}

/* ... */

Square s = new Square();
Rectangle r = new Rectangle();
System.out.println("Check: " + check(s, r));
public int isLargerThan(Relatable other) {

    if (this.getSize() < other.getSize())
        return -1;
    else if (this.getSize() > other.getSize())
        return 1;
    else
        return 0;               
}
注意: 因为几个不同的类可以实现Relatable,所以必须检查isLargerThan参数的类型,否则会遇到类型转换异常

也许您可以在Relatable中指定类似的内容

public int getSize();
您可以这样编写isLargeThan方法:

/* ... */

public static int check(Relatable a, Relatable b) {
  return a.isLargerThan(b);
}

/* ... */

Square s = new Square();
Rectangle r = new Rectangle();
System.out.println("Check: " + check(s, r));
public int isLargerThan(Relatable other) {

    if (this.getSize() < other.getSize())
        return -1;
    else if (this.getSize() > other.getSize())
        return 1;
    else
        return 0;               
}
public int isLargerThan(相关其他){
if(this.getSize()other.getSize())
返回1;
其他的
返回0;
}

那么就不需要类型转换了。

我必须承认,您展示的java文档中的示例非常糟糕,令人困惑。 这是不好的,因为它在层次结构中包含了一个不安全的强制转换。 向上转换(从实现类到接口/超类)总是安全的,但在可能的情况下应避免向下转换

理想情况下,
Relatable
接口还应该包含
getArea()
方法:

public interface Relatable { 
    public int isLargerThan(Relatable other);
    public int getArea();
}
现在,你不需要丑陋的演员阵容,只要:

public int isLargerThan(Relatable other) { 
    if (this.getArea() < other.getArea()) { 
        return -1; 
    } else if (this.getArea () > other.getArea()) { 
        return 1; 
    } else {
        return 0;
    }
}
public int isLargerThan(相关其他){
如果(this.getArea()other.getArea()){
返回1;
}否则{
返回0;
}
}
public int isLargerThan(Relatable other) { 
    if (this.getArea() < other.getArea()) { 
        return -1; 
    } else if (this.getArea () > other.getArea()) { 
        return 1; 
    } else {
        return 0;
    }
}