ENH: implement ExtensionArray.__array_ufunc__
This implements `ExtensionArray.__array_ufunc__` with minimal behavior changes (xref https://github.com/numpy/numpy/issues/20044 cc @shoyer).  The only real behavior change is that np.abs, np.positive, np.negative wrap TimedeltaArray instead of returning ndarray[td64]

After this comes `Index.__array_ufunc__`
> The only real behavior change is that np.abs, np.positive, np.negative wrap TimedeltaArray instead of returning ndarray[td64]


thi s is user visible right? if so pls add a whatsnew note, otherwise lgtm.