Your approach is not bad, although you should declare mergeA and
mergeB functions as protected since they should not be exposed, but
you would need some type check and casting before calling mergeA and
mergeB.
Another approach would be defining this in the base class (without
overloading any of these functions):
public abstract class Base
{
public int val {get;set;}
public bool merge(Base

You missed this bit:
by declaring at least one constructor
That's what's preventing the default constructor from being created.
The example given has a default access (package access) constructor:
PackageOnly() { }
... so it satisfies both conditions: a) it declares at least one
constructor; b) it declares no public constructors.