Заводские методы не актуальны. Как в вашем первом случае, так и для классов case они просто вызывают конструктор, и поэтому код можно упростить до
new Companion("foo") == new Companion("foo")
и
new Case("foo") == new Case("foo")
, поскольку Companion
не переопределяет equals
(или наследование от переопределения класса / признака equals
), вы получаете определение Object
, которое является ссылочным равенством и ложью для любых двух разных экземпляров.
Case
переопределяет equals
потому что это класс case, а реализация просто сравнивает s
значения.