title: Overloading addition in an abstract class
body: <p>I was trying to figure out how to overload the <code>__add__</code> method in python for an abstract class, but was unable to. Here is the problem I am trying to solve:</p>
  <pre><code>import numpy as np 
  from abc import ABC, abstractmethod
  
  class RandomVariable(ABC):
      @abstractmethod
      def sample(self):
          pass
      
      # I want to override the __add__ method 
      # to return a random variable
      # such that the sample method is the addition from 
      # left.sample() and right.sample()
      
  class NormalVariable(RandomVariable):
      def __init__(self, mu=0, sigma=1):
          self.mu = mu
          self.sigma = sigma
      def sample(self):
          return np.random.normal(self.mu, self.sigma)
  
  class ExponentialVariable(RandomVariable):
      def __init__(self, scale=1):
          self.scale=scale
      def sample(self):
          return np.random.exponential(self.scale)
  </code></pre>
  <p>That is, I want to be able to do something like <code>my_random_variable = NormalVariable() + ExponentialVariable()</code>.</p>
  <p><strong>Edit</strong></p>
  <p>Is this the standard way of solving it:</p>
  <pre><code>import numpy as np 
  from abc import ABC, abstractmethod
  
  
  
  class RandomVariable(ABC):
      @abstractmethod
      def sample(self):
          pass
      
      def __add__(self, other):
          return AddedVariable(left=self, right=other)
      
      
  class NormalVariable(RandomVariable):
      def __init__(self, mu=0, sigma=1):
          self.mu = mu
          self.sigma = sigma
      def sample(self):
          return np.random.normal(self.mu, self.sigma)
  
  class ExponentialVariable(RandomVariable):
      def __init__(self, scale=1):
          self.scale=scale
      def sample(self):
          return np.random.exponential(self.scale)
      
      
  class AddedVariable(RandomVariable):
      def __init__(self, left, right):
          self.left = left 
          self.right = right
      def sample(self):
          return self.left.sample() + self.right.sample()
  </code></pre>