Reduce one for loop to decrease time complexity
The second loop can be eliminated by creating a 2D array by tiling the self.x array with the np.tile method. The removal of elements in de 1D array with np.delete can than be replaced with a boolean mask (unfortunately this results in a 1D array which needs to be reshaped).
The calculation of the 2D array can be done outside the first loop, as can be the calculation of lower as they do not depend on x.
See my rewrite of the __call__ method:
def __call__(self,x):

    y_interp = np.zeros(len(x))
    
    n = self.degree + 1
    mask =  ~np.eye(n, dtype=np.bool)

    tiled = np.tile(self.x, (n,1))
    masked = np.reshape(tiled[mask], (n, n-1))

    lower = np.prod(self.x[:,np.newaxis] - masked, axis=1)
    
    for i in range(len(x)):

        upper = np.prod(masked -x[i], axis=1)
        
        y_interp[i] = np.sum((upper/lower) * self.y)
           
    return y_interp