简体   繁体   English

在Java中使用复杂的类声明泛型变量

[英]Declaring generic variables with complex class in Java

I have a class to calculate with complex numbers, a real part and an imaginary part as double type. 我有一个用复数计算的类,一个实部和一个虚部为double型。 In other part I have a rational class to calculate rational numbers. 在另一部分中,我有一个有理类来计算有理数。 Now I want that my complex class can operate when the real part and the imaginary part are rational numbers. 现在,我希望我的复数类可以在实部和虚部是有理数时运行。 I've read some docs about generics but I don't know how to declare real part and imaginary part as generic types and use methods as add 2 complex numbers when the real and imaginary parts are doubles or rationals. 我已经阅读了一些有关泛型的文档,但是我不知道如何将实部和虚部声明为泛型,并且当实部和虚部为双精度或有理数时,如何使用方法将2个复数相加。 This is my test code: 这是我的测试代码:

import java.util.regex.Pattern;

public class Complex {
    private double real;
    private double imaginary;
    private Rational qreal;
    private Rational qimaginary;

    public Complex(double real, double imaginary) {
        super();
        this.real = real;
        this.imaginary = imaginary;
    }
    public Complex(Rational real, Rational imaginary) {
        this.qreal = real;
        this.qimaginary = imaginary;
    }
    public Complex(String z) {
        z = z.replaceAll(" ","");
        if(z.contains("i") || z.contains("j")){
            if(z.contains("+")) {
                String[] z1 = z.split(Pattern.quote("+"));
                this.real = Double.parseDouble(z1[0]);
                this.imaginary = Double.parseDouble(z1[1].substring(0, z1.length-1));
            }
            else if(z.contains("-")) {
                String[] z1 = z.split(Pattern.quote("-"));
                this.real = Double.parseDouble(z1[0]);
                this.imaginary = -Double.parseDouble(z1[1].substring(0, z1.length-1));
            }
            else System.out.println("Syntax Error");
        }
        else System.out.println("The complex must only contains i or j as imaginary unit");
    }
    public double getReal() {
        return real;
    }
    public void setReal(double real) {
        this.real = real;
    }
    public double getImaginary() {
        return imaginary;
    }
    public Rational getQreal() {
        return qreal;
    }
    public void setQreal(Rational qreal) {
        this.qreal = qreal;
    }
    public Rational getQimaginary() {
        return qimaginary;
    }
    public void setQimaginary(Rational qimaginary) {
        this.qimaginary = qimaginary;
    }
    public void setImaginary(double imaginary) {
        this.imaginary = imaginary;
    }

    Complex opposite(Complex z) {return new Complex(-z.real, -z.imaginary);}
    double abs() {return Math.hypot(this.real, this.imaginary);}
    Complex conjugate() {return new Complex(real, -imaginary);}
    Complex inverse() {
        if(this.real == 0 && this.imaginary == 0) return new Complex(Double.NaN, Double.NaN);
        else {
            Complex c = this.conjugate();
            double abs_square = Math.pow(this.abs(), 2.);
            return new Complex(c.real / abs_square, c.imaginary / abs_square);
        }
    }

    Complex add2(Complex z) {
        System.out.println("Suma " + this.qreal.add(z.qreal) + " " + this.qimaginary.add(z.qimaginary) + "i");
        return new Complex(this.qreal.add(z.qreal), this.qimaginary.add(z.qimaginary));
    }
    Complex add(Complex z) {return new Complex(this.real + z.real, this.imaginary + z.imaginary);}
    Complex subtract(Complex z) {return add(z.opposite(z));}
    Complex product(Complex z) {
        double r, i;
        r = this.real * z.real - this.imaginary * z.imaginary;
        i = this.real * z.imaginary + this.imaginary * z.real;
        return new Complex(r, i);
    }
    Complex div(Complex z) {
        Complex num = this.product(z.conjugate());
        double den = Math.pow(Math.hypot(z.real, z.imaginary), 2.);
        return new Complex(num.real / den, num.imaginary / den);
    }
    /* (non-Javadoc)
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {
        return "Complex [real=" + real + ", imaginary=" + imaginary + ", qreal=" + qreal + ", qimaginary=" + qimaginary
                + "]";
    }


    /*@Override
    public String toString() {
        if(imaginary > 0.) {
            if (imaginary == 1.)
                return real + " + " + "i";
            return real + " + " + imaginary + "i";
        }
        else if(imaginary < 0.) {
            if (imaginary == -1.)
                return real + " - " + "i";
            return real + " " + imaginary + "i";
        }
        else if(imaginary == 0.)
            return "" +  real;
        else if(real == 0.)
            return  imaginary + "i";
        else
            return "0";
    }*/



}

If you see the code I've implemented 2 add methods but i want only one,and so that for the other methods, toString() too. 如果您看到的代码,我已经实现了2个add方法,但是我只想要一个,因此对于其他方法,toString()也是如此。

Generics are useful when you want to preserve type information. 当您要保留类型信息时,泛型很有用。 But the generic type still needs to have some known interface in order to use it. 但是泛型类型仍然需要具有一些已知的接口才能使用它。 Since double and Rational don't share common interface, it will not be possible to directly create a generic implementation that works for both types. 由于doubleRational不共享公共接口,因此无法直接创建适用于两种类型的通用实现。

What you could do is create an interface Complex with 2 implementations, DoubleComplex and RationalComplex : 您可以做的是使用DoubleComplexRationalComplex两个实现创建一个Complex接口:

public interface Complex<T> {

    T getReal();
    T getImaginary();

    Complex<T> opposite(Complex<T> z);
    double abs();
    Complex<T> conjugate();
    Complex<T> inverse();

    Complex<T> add(Complex<T> z);
    Complex<T> subtract(Complex<T> z);
    Complex<T> product(Complex<T> z);
    Complex<T> div(Complex<T> z);

}

public class DoubleComplex implements Complex<Double> {

    private final double real;
    private final double imaginary;

    ...

    @Override
    public Complex<Double> add(Complex<Double> z) {
        return new DoubleComplex(this.real + z.getReal(), this.imaginary + z.getImaginary());
    }

    ...
}

public class RationalComplex implements Complex<Rational> {

    private final Rational real;
    private final Rational imaginary;

    ...

    @Override
    public Complex<Rational> add(Complex<Rational> z) {
        return new RationalComplex(this.real.add(z.getReal()), this.imaginary.add(z.getImaginary()));
    }

    ...
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM