REF (string): de-duplicate str_endswith, startswith
<s>This adds a _object_compat attribute to govern whether the subclass uses object-dtype semantics in cases where they differ.</s><b>update</b>_object_compat turned out to be unnecessary.


> This adds a _object_compat attribute to govern whether the subclass uses object-dtype semantics in cases where they differ.

The question also is to what extent we necessarily _want_ to keep this difference. I don't have a strong opinion on what `ArrowDtype(pa.string())` should do (I am also fine with it being a more "strictly using pyarrow" version, for now), but aligning the behaviour would simplify the implementation .. (cc @mroeschke) >  I don't have a strong opinion on what ArrowDtype(pa.string()) should do (I am also fine with it being a more "strictly using pyarrow" version, for now)

This is my general hope for `ArrowExtensionArray` and it's behaviors generally to match pyarrow as closely as possible. > The question also is to what extent we necessarily want to keep this difference. I don't have a strong opinion on what ArrowDtype(pa.string()) should do (I am also fine with it being a more "strictly using pyarrow" version, for now), but aligning the behaviour would simplify the implementation

I don't have an opinion on the behavior, but would prefer to keep behavior-changing PRs separate from REF/de-dup PRs. ```
  /home/runner/work/pandas/pandas/pandas/core/arrays/_arrow_string_mixins.py:129:16 - error: Invalid conditional operand of type "bool | NDArray[bool_] | NDFrame"
    Method __bool__ for type "NDFrame" returns type "NoReturn" rather than "bool" (reportGeneralTypeIssues)
  /home/runner/work/pandas/pandas/pandas/core/arrays/_arrow_string_mixins.py:154:16 - error: Invalid conditional operand of type "bool | NDArray[bool_] | NDFrame"
    Method __bool__ for type "NDFrame" returns type "NoReturn" rather than "bool" (reportGeneralTypeIssues)
```

i dont understand these complaints lint complaints fixed! I think comments have been addressed here