Purpose: Learn about classes which can be instantiated as an object through the example of complex numbers.
By now you have some experience creating a Java project following the HelloWorld tutorial. Follow the directions below to create new project.
A package is just a collection of java classes. It is stored on the computer as a folder or directory.
A complex number consists of a real and imaginary part. We will create a class which stores this data (the fields of the class).
public final class Complex {
public final class Complex { final private double x, y; }
This line indicates that a Complex number will contain two variables x and y each of which stores a double value (the real and imaginary parts, respectively).
There are two modifiers in this statement. The word "private" means that we will only be able to access these variables (directly) from functions within this class. The word "final" means that once the values of x and y are set, they are permanent. This contributes toward the goal of making the class immutable.
We will create two constructors. They appear as follows:
public final class Complex { final private double x, y; public Complex(double real_part, double imaginary_part) { x = real_part; y = imaginary_part; } public Complex(double real_part) { x = real_part; y = 0; } }
The first constructor takes as input two doubles, and sets the variables x and y using this input.
The second constructor produces a real number from just one input.
public static Complex fromPolar(double r, double theta) { return new Complex(r*Math.cos(theta), r*Math.sin(theta)); }
Because of the static keyword, the method can be called by referring directly to the class. For instance, we can construct a 7th root of unity with the line:
Complex z = Complex.fromPolar(1,2*Math.PI/7);
The following are some of the methods from the Complex class.
public double re(){ return x; }The absence of the static keyword means that this method can only be called from a Complex object. For instance, the following is a reasonable way to to use this method:
Complex z = Complex.fromPolar(1,2*Math.PI/7); System.out.println("The number "+z.re()+" is the real part of a 7th root of unity.");
public double absSquared() { return x*x+y*y; }
public double abs() { return Math.sqrt(absSquared()); }Note that this code calls our absSquared method and then uses a static method from java.lang.Math to compute the square root. (A static method can be called just using the class name, while most methods such as our method re() require an object to call them.)
public double conj(){ return new Complex(x,-y); }Note that this method calls one of our constructors.
public Complex add(Complex z) { return new Complex(x+z.x, y+z.y); }
public Complex inv() { double abs_squared=absSquared(); return new Complex(x/abs_squared, -y/abs_squared); }
You can also view these functions in the Complex.java file. The source code in Complex.java is well commented. If you have questions, these comments might help to answer them.
Every class extends the java.lang.Object class. This means that you can call all the methods from the Object class on any object that appears in Java. (This includes pretty much everything, except arrays and primitive types such as int and double.)
public String toString() { if (y==0) { return ""+x; } if (y>0) { return ""+x+"+"+y+"*I"; } return ""+x+"-"+(-y)+"*I"; }
To understand this code, recall that adding to a string has the effect of concatenation. So the line return ""+x;, returns the string formed by concatenating the empty string "" and x. Here, x is converted to a string using whatever Java's standard format for doubles is in Java.
We taylor what we return to the particular complex number. So we convert only the real part if the imaginary part is zero. Otherwise we print both parts. We also carefully consider the sign in front of the imaginary part.
You can also do much more fancy number formatting with java, but there is no need to worry about this until you need to. See the links at the end of this page.
In particular, we need to be able to compare a complex number with any object in Java. This makes the code of this method more complex, fortunately, NetBeans has a shortcut for overriding this method, which generates the following code:
public boolean equals(Object obj) { if (obj == null) { return false; } if (!(obj instanceof Complex)) { return false; } Complex other = (Complex) obj; if (x != other.x) { return false; } if (y != other.y) { return false; } return true; }Here is a detailed explanation of what this function is doing:
As mentioned above, NetBeans has the ability to write an equals method for you. To achieve this, be sure your class does not have an equals method.
Slightly technical remark: The hashcode() function returns an int. The implementation of this function is supposed to guarantee that whenever to objects are equal, they return the same hashcode. This is useful for quickly assembling a collection of distinct objects. See the documentation for HashSet and HashMap for instance.
This class should have been created when you created the project. The source is below:
import number.Complex; // Allow us to use our complex class public class ComplexDemo { public static void main(String[] args) { Complex a=new Complex(1.41235123,2.3145432), b=new Complex(3,4); System.out.println("I created two complex numbers: a="+a+" and b="+b+"."); System.out.println("The absolute values of these numbers are |a|="+a.abs()+ " and |b|="+b.abs()+"."); System.out.println("The sum of these numbers is a+b="+a.add(b)+"."); System.out.println("The difference between these numbers is a-b="+a.minus(b)+"."); System.out.println("The product of these numbers is a*b="+a.mult(b)+"."); System.out.println("The ratio of these numbers is a/b="+a.div(b)+"."); System.out.println("A sanity check: (b/a)*a-b="+b.div(a).mult(a).minus(b) +"."); Complex z = Complex.fromPolar(1,2*Math.PI/7); System.out.println("A primitive 7th root of unity is "+z+"."); } }
To run the program select "Run > Run Main Project" using the NetBeans menus.
You can also do more complex number formatting. See the Number formatting part of the tutorial.