Is there a way to alter a form, implemented by another module, using a class?
Drupal core code still uses hook_form_alter() (or hook_form_BASE_FORM_ID_alter(), or hook_form_FORM_ID_alter()) for that purpose.
You could alter a route and change the form associated with that route, but this would mean that:


You would need to keep track of the form class that was associated to that route before you changed it; in this way, you would be able to let the previous class add its own form fields
You would need to alter all the routes using that form class, in order to make Drupal use your class


The closer I could see used from Drupal code, which means the code would be in a class, is what the Content moderation module does in content_moderation_form_alter().

function content_moderation_form_alter(&amp;$form, FormStateInterface $form_state, $form_id) {
  \Drupal::service('class_resolver')
    -&gt;getInstanceFromDefinition(EntityTypeInfo::class)
    -&gt;formAlter($form, $form_state, $form_id);
}


Using that, you have the pro of using object-oriented code, allow other modules to extend the same form without complicating your code, and without interfering with code used from other modules.

Since the Drupal API page doesn't link the EntityTypeInfo class, it's the class defined in core/modules/content_moderation/src/EntityTypeInfo.php.

The relevant code is the following one, which shows how a class method is used as form submission handler.

  /**
   * Alters bundle forms to enforce revision handling.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   * @param string $form_id
   *   The form id.
   *
   * @see hook_form_alter()
   */
  public function formAlter(array &amp;$form, FormStateInterface $form_state, $form_id) {
    $form_object = $form_state-&gt;getFormObject();
    if ($form_object instanceof BundleEntityFormBase) {
      $type = $form_object-&gt;getEntity()-&gt;getEntityType();
      if ($this-&gt;moderationInfo-&gt;canModerateEntitiesOfEntityType($type)) {
        $this-&gt;entityTypeManager-&gt;getHandler($type-&gt;getBundleOf(), 'moderation')-&gt;enforceRevisionsBundleFormAlter($form, $form_state, $form_id);
      }
    }
    elseif ($form_object instanceof ContentEntityFormInterface) {
      $entity = $form_object-&gt;getEntity();
      if ($this-&gt;moderationInfo-&gt;isModeratedEntity($entity)) {
        $this-&gt;entityTypeManager
          -&gt;getHandler($entity-&gt;getEntityTypeId(), 'moderation')
          -&gt;enforceRevisionsEntityFormAlter($form, $form_state, $form_id);
        // Submit handler to redirect to the latest version, if available.
        $form['actions']['submit']['#submit'][] = [EntityTypeInfo::class, 'bundleFormRedirect'];
      }
    }
  }


This is the form submission handler that method is using.

  /**
   * Redirect content entity edit forms on save, if there is a forward revision.
   *
   * When saving their changes, editors should see those changes displayed on
   * the next page.
   *
   * @param array $form
   *   An associative array containing the structure of the form.
   * @param \Drupal\Core\Form\FormStateInterface $form_state
   *   The current state of the form.
   */
  public static function bundleFormRedirect(array &amp;$form, FormStateInterface $form_state) {
    /* @var \Drupal\Core\Entity\ContentEntityInterface $entity */
    $entity = $form_state-&gt;getFormObject()-&gt;getEntity();

    $moderation_info = \Drupal::getContainer()-&gt;get('content_moderation.moderation_information');
    if ($moderation_info-&gt;hasForwardRevision($entity) &amp;&amp; $entity-&gt;hasLinkTemplate('latest-version')) {
      $entity_type_id = $entity-&gt;getEntityTypeId();
      $form_state-&gt;setRedirect("entity.$entity_type_id.latest_version", [$entity_type_id =&gt; $entity-&gt;id()]);
    }
  }


As you see, it's not the same as extending FormBase, but it's more OOP than using plain functions.