java - 接口(interface)和类型转换

标签 java

在关于接口(interface)的 Java 8 教程中,one example表示当类实现接口(interface)时,必须将接口(interface)类型强制转换为类类型才能调用此类的方法,如 java 8 教程中的以下示例所示:

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

    // four constructors
    public RectanglePlus() {
        origin = new Point(0, 0);
    }
    public RectanglePlus(Point p) {
        origin = p;
    }
    public RectanglePlus(int w, int h) {
        origin = new Point(0, 0);
        width = w;
        height = h;
    }
    public RectanglePlus(Point p, int w, int h) {
        origin = p;
        width = w;
        height = h;
    }

    // a method for moving the rectangle
    public void move(int x, int y) {
        origin.x = x;
        origin.y = y;
    }

    // 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;               
    }
} 

在方法 isLargerThan(Relatable other) 中,other 被强制转换为 RectanglePlus 类型,以便调用 getArea()。 在 other example关于接口(interface)中的默认方法,compareTo(Card o)方法不会将类型转换o转换为类型PlayingCard,但可以直接调用int hashCode(),我不这样做了解这个。感谢您的帮助。

package defaultmethods; 

public class PlayingCard implements Card {

    private Card.Rank rank;
    private Card.Suit suit;

    public PlayingCard(Card.Rank rank, Card.Suit suit) {
        this.rank = rank;
        this.suit = suit;
    }

    public Card.Suit getSuit() {
        return suit;
    }

    public Card.Rank getRank() {
        return rank;
    }

    public boolean equals(Object obj) {
        if (obj instanceof Card) {
            if (((Card)obj).getRank() == this.rank &&
                ((Card)obj).getSuit() == this.suit) {
                return true;
            } else {
                return false;
            }
        } else {
            return false;
        }
    }


    public int hashCode() {
        return ((suit.value()-1)*13)+rank.value();
    }

    public int compareTo(Card o) {
        return this.hashCode() - o.hashCode();
    }

    public String toString() {
        return this.rank.text() + " of " + this.suit.text();
    }

    public static void main(String... args) {
        new PlayingCard(Rank.ACE, Suit.DIAMONDS);
        new PlayingCard(Rank.KING, Suit.SPADES);
    }
}

最佳答案

简而言之:因为 hashCode 是在 java.lang.Object 中定义的所有其他类都隐式扩展 Object

所以当你有

public int compareTo(Card o) {
    return this.hashCode() - o.hashCode();
}

编译器已经知道oCard类型,它扩展了Object,后者定义了hashCode方法。无需显式强制转换。

另一方面,在您的 isLargerThan 方法中,参数的类型为 Relatable:

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;               
}

从您提供的链接来看,getArea方法仅在RectanglePlus中定义。由于编译器仅看到 Relatable 它此时不知道有关 getArea 方法的任何信息,因此您需要显式地将 other 转换为 RectanglePlus 才能访问它。

请注意,您实际上应该在转换之前进行 instanceof 检查,以避免在 other 不存在时出现 ClassCastException a RectanglePlus (您不知道是否还有其他类实现 Relatable)。

让我尝试一个与代码无关的示例:

如果人们养宠物,他们通常会给它起一个名字。因此,无论您拥有什么宠物,人们都可以随时询问其名称(参见 hashCode)。但他们不能要求你让它(参见getArea),除非他们知道这是一只狗。 而且你可能无法让猫(参见ClassCastException)。

关于java - 接口(interface)和类型转换,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48966301/

相关文章:

java - 通过Java读取XML中的转义序列

java - 如何判断一个对象属于某个特定的类

java - 如何为正在运行的倒计时器添加时间?

java - Java 中的嵌套复选框

java - Jackson vs. Spring HATEOAS vs. 多态性

java - 有没有办法在 Java 中强制对弱和/或软引用对象进行 GC?

java - 如何解析无效(错误/格式不正确)的 XML?

java - Google 应用内购买返回错误代码 6

java - Java 中 XMLGregorianCalendar 的 NoClassDefFoundError

java - 准备多值国家 map