我正在尝试编写一个实现Comparable接口的'Cup'类。
我的代码:
func findFriends(text: String) -> Void {
let ref = Database.database().reference()
ref.child("users").queryOrdered(byChild: "username").queryStarting(atValue: text).queryEnding(atValue: text+"\u{f8ff}").observe(.value, with: { snapshot in
let user = User()
let userArray = [User]()
for u in snapshot.children{
user.name = u.value!["name"] as? String
}
})
但是程序抛出错误说明:
class Cup<T> implements Comparable<T>{
public T radius;
public T height;
public Cup(T radius, T height){
this.radius = radius;
this.height = height;
}
public double getVolume(){
return (double) radius * (double) radius* (double) height* 3.14 ; // throwing error
}
public int compareTo(Object cup){
if(getVolume()== ((Cup) cup).getVolume()){ // cannot access java.lang.Comparable
return 0;
}
else if(getVolume() > ((Cup) cup).getVolume()){
return 1;
}
else if(getVolume() < ((Cup) cup).getVolume()){
return -1;
}
return -2;
}
}
class test{
public static void main(String[] args) {
Cup<Integer> mycup = new Cup<Integer>(5,5);
Cup<Integer> momscup = new Cup<Integer>(7,7);
mycup.compareTo(momscup);
}
}
。
我不是要转换为Double,而是要转换为Double。为什么会引发错误?
谢谢
答案 0 :(得分:5)
我不是要转换为Double,而是要转换为Double。为什么会引发错误?
问题的根源是T
的静态类型是Object
而不是Integer
。因此,编译器已确定以下路径可能有效:
Double
(需要运行时检查)Double
开箱到double
。问题是Integer
无法转换为Double
。
最好的解决方案是这样:
class Cup<T extends Number> implements Comparable<T> {
...
public double getVolume(){
return radius.doubleValue() * radius.doubleValue()
height.doubleValue() * Math.PI;
}
这是静态类型安全的(对您可能在其他地方执行的任何不安全的转换进行模运算)。
请注意,如果将T
替换为Integer
,则编译器将使用其他路径进行转换:
Integer
开箱到int
。int
扩展为double
。 取决于确切地编写πr 2 h表达式的方式,类型转换可能是不必要的。
答案 1 :(得分:2)
实际上,您实际上是在botium-ScriptingProvider undefined PARTIAL_HELLO ({ convoDir: 'sample/', filename: 'example.pconvo.txt' }): Line 3: #me - Hello, Bot! | Line 6: #bot - You said: Hello, Bot! +0ms
上隐式添加一个强制类型转换,因此您将获得异常。
我建议您对课程进行如下更改:
Double
仔细查看我如何更改class Cup<T extends Number> implements Comparable<Cup<T>> {
public T radius;
public T height;
public Cup(T radius, T height) {
this.radius = radius;
this.height = height;
}
public double getVolume() {
return radius.doubleValue() * radius.doubleValue() * height.doubleValue() * 3.14;
}
@Override
public int compareTo(Cup<T> cup) {
return Double.compare(getVolume(), cup.getVolume());
}
}
方法和compareTo
方法以使其更具可读性。
在完成这些更改之后,您将无法运行测试:
getVolume
以下是我建议您进行的更改,以便您可以学习。
class test {
public static void main(String[] args) {
Cup<Integer> mycup = new Cup<>(5, 5);
Cup<Integer> momscup = new Cup<>(7, 7);
mycup.compareTo(momscup);
}
}
,这是一种方便的方法,已经可以用来完成您想要的操作。Double.compare
。@Override
初始化时,您无需再次在右侧提及Cup<Integer> mycup = new Cup<>(5, 5);
。 (如果您使用的是JDK 7或更高版本,则可以这样做)答案 2 :(得分:0)
半径和高度属性定义为T,但是将它们强制转换为double,则应将它们声明为double或使类的Generic类型扩展Number,Number是Double和Integer的抽象父类
class Cup<T extends Number> {
public T radius;
public T height;
public Cup(T radius, T height) {
this.radius = radius;
this.height = height;
}
public double getVolume() {
return radius.doubleValue() * radius.doubleValue() * height.doubleValue() * 3.14; // throwing error
}
}
class test {
public static void main(String[] args) {
Cup<Integer> mycup = new Cup<Integer>(5, 5);
Cup<Integer> momscup = new Cup<Integer>(7, 7);
System.out.println(mycup.getVolume());
}
}