Class and Object (Instance)
- A class is a blueprint for creating objects; an object is an instance of that blueprint.
- A circle requires a center point and a radius, which become the
Circleclass’s data fields. - The center point is modeled as a
Pointclass encapsulatingxandycoordinates.
Access Modifiers (public, private, package-default, protected)
- private: Members are accessible only within their class. Instance variables should be private to maintain data integrity (bank account analogy).
- public: Members are accessible from any class. Common for methods (like getters) that expose controlled access to private data. The main method must be public for the Java runtime to invoke it.
- package (default): If no modifier is specified, the member is accessible only within the same package. (BTW, don’t include package declarations from some IDEs when submitting to OJ.)
- protected: Mentioned in the context of inheritance (will be covered in a future lecture). Members are accessible to subclasses.
Method
Overridingvs.Overloading- Overriding: A subclass provides a specific implementation for a method defined in its parent. Example: overriding
toString()in Point to return readable coordinates instead of a memory address. - Overloading: Multiple methods in the same class share a name but differ in parameters (number, type). Circle demonstrates this with two constructors: one taking a Point and a double (radius), and another taking three Point objects. The compiler selects the appropriate method based on arguments.
- Overriding: A subclass provides a specific implementation for a method defined in its parent. Example: overriding
A
finalvariable cannot change after initialization, enabling immutable objects (e.g., fixed point coordinates).The
staticKeyword- static members belong to the class, not instances.
- Static Variable:
private static int count = 0;tracks the total number of Circle objects, incremented in each constructor and shared across instances. - Static Method:
public static int getCount()returns the current count. - Static Context Constraint: Static methods cannot access instance members directly. E.g., attempting to access instance variable
rin the static methodgetCount()causes a compiler error because no specific object instance is available.
Implementation of the Class
- Always use
doubleto represent real numbers in Java as it has higher precision thanfloat. thisis used when parameter names match instance variables (e.g.,this.x = x;). Here,this.xreferences the field,xreferences the parameter. If parameters use different names (e.g.,init_x), assignments likex = init_x;do not requirethis.- Handling Floating-Point Precision: Avoid direct equality checks (
==) with double. Use a small tolerance EPS (epsilon) (e.g., $10^{-6}$).
- Always use
Code for the Robust Circle, throwing exception is not required in the simple Circle problem:
class Point { private final double x; private final double y; public double getX() { return x; } public double getY() { return y; } public Point(double x, double y) { this.x = x; this.y = y; } @Override public String toString() { return x + " " + y; } public double dis(Point o) { double dx = x - o.x; double dy = y - o.y; return Math.hypot(dx, dy); } public static double dis(Point a, Point b) { double dx = a.x - b.x; double dy = a.y - b.y; return Math.hypot(dx, dy); } } class InvalidRadiusException extends Exception { public InvalidRadiusException() { super(); } } class CollinearPointsException extends Exception { public CollinearPointsException() { super(); } } public class Circle { private final Point c; private final double r; private static int cnt = 0; // public static void main(String[] args) // { // Point a = new Point(0.0, 0.1); // Point b = new Point(1.0, 2.0); // // a.dis(b); // Point.dis(a, b); // } public static int getCnt() { return cnt; } public Point getCenter() { return c; } public double getR() { return r; } public Circle(Point c, double r) throws Exception { if (c == null) throw new NullPointerException(); if (r <= 0) throw new InvalidRadiusException(); this.c = c; this.r = r; cnt++; } public Circle(Point a, Point b, Point c) throws Exception { if (a == null || b == null || c == null) throw new NullPointerException(); double x1 = a.getX(), y1 = a.getY(); double x2 = b.getX(), y2 = b.getY(); double x3 = c.getX(), y3 = c.getY(); double EPS = 1e-6; double D = 2 * (x1 * (y2 - y3) + x2 * (y3 - y1) + x3 * (y1 - y2)); if (Math.abs(D) < EPS) throw new CollinearPointsException(); double sq1 = x1 * x1 + y1 * y1; double sq2 = x2 * x2 + y2 * y2; double sq3 = x3 * x3 + y3 * y3; double Ux = (sq1 * (y2 - y3) + sq2 * (y3 - y1) + sq3 * (y1 - y2)) / D; double Uy = (sq1 * (x3 - x2) + sq2 * (x1 - x3) + sq3 * (x2 - x1)) / D; Point U = new Point(Ux, Uy); double R = U.dis(a); if (R <= 0) throw new InvalidRadiusException(); this.c = U; r = R; cnt++; } public double circumference() { return Math.PI * 2 * r; } public double area() { return Math.PI * r * r; } public Boolean joins(Circle o) throws Exception { if (o == null) throw new NullPointerException(); double EPS = 1e-6; double d = c.dis(o.c); return (Math.abs(r - o.r) <= d + EPS) && (d <= r + o.r + EPS); } }