在关于接口(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();
}
编译器已经知道o
是Card
类型,它扩展了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/