A solution to problem 6.18 along with some code to test if the methods are written correctly.

First, a class containing main.

```public class Main {
public static void main(String[] meow) {
Line a = new Line(-2, 1.5);
Line b = new Line(0, 1, 2, 2);
Line c = new Line(1, 3, -2);
Line d = new Line(4);
Line e = new Line(-2, 5);
System.out.println(b.getSlope() + " " + b.getIntercept());
System.out.println(a.isParallel(b));   // false
System.out.println(a.isParallel(c));   // true
System.out.println(a.isPerpendicular(b));  // m1=-2, m2=.5
System.out.println(a.equals(b));       // false
System.out.println(e.equals(c));       // true
}
}
Now, the Line class.

public class Line {
private double m;    // slope
private double b;    // y-intercept
private boolean isVertical = false;
private double k;

// Assume that for all constructors except the
// single input constructor (i.e., x = k), there
// will be no division by zero (i.e., x1 != x2).

// Given m, b
public Line(double m, double b) {
this.m = m;
this.b = b;
}

// Given a point and slope, find the y-intercept
public Line(double x1, double y1, double m) {
this.m = m;
b = y1 - (m*x1);
}

// Given two points, must find slope and y-intercept
public Line(double x1, double y1, double x2, double y2) {
m = (y2-y1)/(x2-x1);
b = y1 - (m*x1);
}

// x = k
public Line(double k) {
isVertical = true;
this.k = k;
}

public double getSlope() { return m; }
public double getIntercept() { return b; }

public boolean isParallel(Line l2) {
if (isVertical && l2.isVertical) return true;
else if (isVertical || l2.isVertical) return false;
else return (m == l2.m);
}

public boolean isPerpendicular(Line l2) {
if (isVertical && !(l2.isVertical)) return (l2.m == 0);
else if (!(isVertical) && l2.isVertical) return (m == 0);
else if (!(isVertical) && !(l2.isVertical))
return (m * l2.m == -1);
else return false;
}

public boolean equals(Line l2) {
return ((isVertical && l2.isVertical && k == l2.k) ||
(!(isVertical) && !(l2.isVertical) && m == l2.m && b == l2.b));
}
}

```