4

嘿,我刚刚开始学习 Java,我很快参加一门课程(是的,我是个书呆子,我在开始上课之前就学习了)。我想把一些概念塞在一起,以了解 Java 中的一切是如何协同工作的。

现在,我想做的是一个简单的 Shape(法语中的 Forme)类,它至少有 1-2 个继承自它的类,并在集合对象中创建一些实例。我也想让这些类泛型来尝试一下。那是我遇到麻烦的部分。

我非常习惯 C++,所以这可能是混乱所在,但似乎我不能使用泛型,例如,我可以指定维度将是,比如,整数或双精度或浮点数或其他. 可能吗 ?

base下面的 GetArea() 方法因为和无法编译hauteur

package testconcepts;

import java.util.*;
import java.lang.*;

abstract class Forme <T extends Number> {
    protected String nom_forme;

    String NomForme() { return nom_forme; }

    abstract Double GetArea();
}

class Triangle <T extends Number> extends Forme {
    protected T base, hauteur;

    Triangle() { 
        this.nom_forme = "TRIANGLE"; 
    }

    @Override
    Double GetArea() { return base * hauteur / 2; }

    T GetBase() { return base; }
    T GetHauteur() { return hauteur; }
    void SetBase(T base) { this.base = base; }
    void SetHauteur(T hauteur) { this.hauteur = hauteur; }
}

public class TestConceptsJava {
    public static void main(String[] args) {
        ArrayList list = new ArrayList();
        list.add(new Triangle<Double>());
    }
}

请注意,由于类型问题,我也无法在构造函数中对 0 进行赋值。

另外,我知道有非常相似的主题,但在其他问题中我还没有找到解决我的问题的方法。

TLDR 如何使用原始类型包装器(Double、Integer..)使工作泛型?

4

5 回答 5

6

所以你的问题是我猜的这条线:

Double GetArea() { return base * hauteur / 2; }

您收到错误的原因*是未定义类型对象的运算符Number。既然你知道你将处理int​​s 和doubles (我假设),你可以试试这个:

Double GetArea() { return base.doubleValue() * hauteur.doubleValue() / 2; }

需要注意的是,通常我们以小写字母开头方法名称,即getArea().

于 2012-10-05T21:11:29.903 回答
3

在 GetArea() 中,您在两个类上调用 * 运算符。说这样的话有多大意义:

Object o1 = //whatever;
Object o2 = //whatever;

return o1 * o2;

不多吧?你不能将两个类相乘。您真正想要做的是乘以这些包装类的基础值(这在 Java 中不会为您隐式完成)。像这样重写 GetArea() 应该可以解决您的问题:

Double GetArea() { return base.doubleValue() * hauteur.doubleValue() / 2; }

请注意,您还必须在该类中您关心的其他任何地方使用基础值。

于 2012-10-05T21:11:36.683 回答
1

您正在寻找的内容称为“自动(取消)装箱”。不幸的是,操作T必须对 的所有子类型有效Number,而“自动(取消)装箱”不是这样的操作(例如,它不适用于BigInteger)。

于 2012-10-05T21:11:56.267 回答
1

更改为Double GetArea() { return base.doubleValue() * hauteur.doubleValue() / 2; }将使代码编译,但这在 Java 中是个坏主意,因为 Java 中的泛型不适用于此。基本上,它们只是在使用对象集合时确保静态类型安全。

Java 没有运算符重载,因此您不能期望*除原始类型之外的任何东西都可以工作。

我建议阅读基本的 Java 泛型教程以了解它们在 Java 中的用途:http: //docs.oracle.com/javase/1.5.0/docs/guide/language/generics.html

于 2012-10-05T21:10:57.037 回答
1

查看计算的这一部分:

base * hauteur

由于和都是 使用包装类声明的,因此您不能像使用原始类型那样使用运算符。相反,您需要显式获取值:basehauteur*

base.doubleValue() * hauteur.doubleValue()

请注意,如果使用原始类型声明base或声明,这将不是问题。hauteur然后,Java 编译器将能够使用自动拆箱将另一个转换为适当的类型,并进行所需的任何隐式转换。

于 2012-10-05T21:11:28.173 回答