Какой из этих подходов в ООП лучше и как они называются?
с самого начала у нас есть более-менее абстрактный класс
Так не должно быть. "абстрактные" классы это способ устранения дублирования, нам больше важны интерфейсы объектов и полиморфизм. Но конкретно в рассматриваемом примере нам важна только инкапсуляция.
Далее оба способа и чем они отличаются. В первом мы просто создаем объект, который уже содержит какое-то состояние по умолчанию. Во втором мы создаем объект с нулевым состоянием, и потом просим его сменить свое состояние на новое.
Вот и вся разница. Далее вход идет инкапсуляция. То есть наше состояние должно быть изолировано внутри объекта, и доступ к нему напрямую из внешнего мира должен быть закрыт. 
Если мы хотим создать объект с каким-то состоянием по умолчанию - мы берем первый вариант (либо как в примере прописывваем прямо как значение свойства, либо  сэтим в конструкторе). 
Если мы хотим создать "пустой" объект и уже потом определить его состояние - мы выбираем второй вариант. Как правило этот способ создает много побочных эффектов если не контролировать его, да и обычно это делают не потому что так правильно а потому что подругому не умеют (типичный пример - сущности доктрины. Многие просто не представляю себе как с ними работать без сеттеров).
Если же мы хотим создать объект но он не может быть пустым, объект должен требовать начальное значение в момент создания. Тогда мы просто передаем значение в конструктор. Без этого значения (или с неправильным) мы не сможем создать объект. К примеру если у пользователя обязательно должен быть email и пароль имеет смысл "заставлять" разработчиков явно передавать их в конструктор объекта. Это эдакая вариация.
А теперь попробуем первый и второй подходы вместе + третий кейс с обязательными параметрами:class User {
     private $id;
     private $email;
     private $password;

     public function __construct($email, $password) 
     {
           // это ваш первый пример только без наследования, оно не нужно
           // в нашей задаче идентификатор пораждается
           // при создании объекта самим объектом, состояние по умолчанию
           $this->id = Uuid::uuid4(); 

           // мы требуем входящие данные что бы задать начальное состояние
           $this->email = $email;
           $this->password = $password;
     }

     // мутация состояния, второй вариант.
     public function changePassword($password) 
     {
            $this->password = $password;
     }
}
То есть вся разница только в том, откуда приходят данные для формирование объектом своего состояния. Изнутри (первый случай) или снаружи (второй случай). Оба подхода вполне себе можно использовать вместе.
Ну и да - зачем в вашем примере наследование и нейкий "абстрактный" класс - не понятно. Наследование это не принцип, это механизм для достижения полиморфизма подтипов. С ним нужно быть осторожно, особенно если с полиморфизмом не разобраться сначала.
Не нужно создавать наследников если в них нет дополнительной логики. Принцип Оккама.