How do I alter the entity type class? In Drupal 8 you can load an entity with:

$node = \Drupal::entityManager()-&gt;getStorage('node')-&gt;load(123);


This looks for the entity definitions and finds that node is defined by Drupal\node\Entity\Node - so (I guess) Drupal\node\NodeStorage will instantiate a new Drupal\node\Entity\Node instance.

What I'd like to achieve is subclassing Drupal\node\Entity\Node and being able to instantiate this subclass when it's appropriate. For example if I have a node bundle article, there would be a class:

namespace Drupal\my_module\Entity\Article;
class Article extends Drupal\node\Entity\Node {
}


And I'd call:

$node = \Drupal::entityManager()-&gt;getStorage('node_article')-&gt;load(123);


And the return would be my Article subclass.

I can achieve this by creating a new entity type and wiring it back to another existing entity definitions, for example the node-article example would be this class:

namespace Drupal\my_module\Entity;
use Drupal\node\Entity\Node;
/**
 * @ContentEntityType(
 *   id = "node_article",
 *   label = @Translation("Content"),
 *   bundle_label = @Translation("Content type"),
 *   handlers = {
 *     "storage" = "Drupal\node\NodeStorage",
 *     "storage_schema" = "Drupal\node\NodeStorageSchema",
 *     "view_builder" = "Drupal\node\NodeViewBuilder",
 *     "access" = "Drupal\node\NodeAccessControlHandler",
 *     "views_data" = "Drupal\node\NodeViewsData",
 *     "form" = {
 *       "default" = "Drupal\node\NodeForm",
 *       "delete" = "Drupal\node\Form\NodeDeleteForm",
 *       "edit" = "Drupal\node\NodeForm"
 *     },
 *     "route_provider" = {
 *       "html" = "Drupal\node\Entity\NodeRouteProvider",
 *     },
 *     "list_builder" = "Drupal\node\NodeListBuilder",
 *     "translation" = "Drupal\node\NodeTranslationHandler"
 *   },
 *   base_table = "node",
 *   data_table = "node_field_data",
 *   revision_table = "node_revision",
 *   revision_data_table = "node_field_revision",
 *   translatable = TRUE,
 *   list_cache_contexts = { "user.node_grants:view" },
 *   entity_keys = {
 *     "id" = "nid",
 *     "revision" = "vid",
 *     "bundle" = "type",
 *     "label" = "title",
 *     "langcode" = "langcode",
 *     "uuid" = "uuid",
 *     "status" = "status",
 *     "uid" = "uid",
 *   },
 *   bundle_entity_type = "node_type",
 *   field_ui_base_route = "entity.node_type.edit_form",
 *   common_reference_target = TRUE,
 *   permission_granularity = "bundle",
 *   links = {
 *     "canonical" = "/node/{node}",
 *     "delete-form" = "/node/{node}/delete",
 *     "edit-form" = "/node/{node}/edit",
 *     "version-history" = "/node/{node}/revisions",
 *     "revision" = "/node/{node}/revisions/{node_revision}/view",
 *   }
 * )
 */
class Article extends Node { }

// Results my Article sub type.
$node = \Drupal::entityManager()-&gt;getStorage('node_article')-&gt;load(123);


This works fine (as much as I can see); however, it smells. It adds a new entity type, which is not true, and might cause other troubles in the future.

How do I define a subclass for an entity bundle so that loading the entity would return an object of that class?
Create a new class in your module that extends \Drupal\node\Entity\Node.

use Drupal\node\Entity\Node as BaseNode;

class MyNode extends BaseNode {
}


Implement hook_entity_type_build().

use Drupal\Core\Entity\EntityTypeInterface;

/**
 * @param EntityTypeInterface[] $entity_types
 */
function my_module_entity_type_build(&amp;$entity_types) {
  if (isset($entity_types['node'])) {
    $entity_types['node']-&gt;setClass('Drupal\my_module\Entity\MyNode');
  }
}


Remember to rebuild the cache.

It works fine when loading nodes via the entity type manager service and the node storage. It even works when you just use Drupal\node\Entity\Node::load($nid) thanks to the fact that this load() function it is just a static wrapper for the entity type manager service call provided by the Entity class which is extended from the Node class.

// Part of Entity class for reference
abstract class Entity implements EntityInterface {
  /**
   * Loads an entity.
   *
   * @param mixed $id
   *   The id of the entity to load.
   *
   * @return static
   *   The entity object or NULL if there is no entity with the given ID.
   */
  public static function load($id) {
    $entity_manager = \Drupal::entityManager();
    return $entity_manager-&gt;getStorage($entity_manager-&gt;getEntityTypeFromClass(get_called_class()))-&gt;load($id);
  }
}


This also works fine with the soon-to-be-removed entity_load_multiple() function, so I guess this covers all standard use cases for loading nodes.

Of course, if your module does this and another module does the same, you'll have a problem, but I guess it's not common scenario, and it makes sense only for very specific use cases.