// Exercise 3: equals/hashCode contract and field hiding
//
// Part A: implement Point.equals and Point.hashCode so that two Points
// with the same x and y are equal AND have the same hash code (required
// for correct behavior in hash-based collections).
//
// Part B: FieldDemoBase / FieldDemoChild demonstrate that FIELDS are not
// polymorphic. Do not "fix" this behavior — the self-check asserts the
// real Java semantics. Just fill in the TODO constructors.

import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

public class java_inheritance_and_polymorphism_exercise_3 {

    static class Point {
        int x, y;

        Point(int x, int y) {
            this.x = x;
            this.y = y;
        }

        @Override
        public boolean equals(Object o) {
            // TODO: implement value equality (same x and y)
            return false;
        }

        @Override
        public int hashCode() {
            // TODO: implement using Objects.hash(x, y)
            return 0;
        }
    }

    static class FieldDemoBase {
        String label = "base";
    }

    static class FieldDemoChild extends FieldDemoBase {
        String label = "child"; // shadows, does NOT override (fields aren't polymorphic)
    }

    // --- self-check: do not modify below this line ---
    public static void main(String[] args) {
        boolean ok = true;

        Point p1 = new Point(1, 2);
        Point p2 = new Point(1, 2);
        Point p3 = new Point(3, 4);

        ok &= p1.equals(p2);
        ok &= !p1.equals(p3);
        ok &= p1.hashCode() == p2.hashCode();

        Set<Point> set = new HashSet<>();
        set.add(p1);
        ok &= set.contains(p2); // works only if equals+hashCode are both correct
        ok &= set.size() == 1;
        set.add(p3);
        ok &= set.size() == 2;

        FieldDemoBase ref = new FieldDemoChild();
        ok &= ref.label.equals("base"); // declared type wins for field access
        ok &= ((FieldDemoChild) ref).label.equals("child"); // cast reveals the shadowed field

        System.out.println(ok ? "PASS" : "FAIL");
    }
}
