Matryoshka Doll Recursion
Naming

Field babushka should be named wearingBabushka, since that is what the field describes. The method accessing it becomes isWearingBabushka(). For some reason Java-people like exceptions in naming standards and are adamant that it's vital to have a non-standard getter name for boolean typed methods (yes I'm bitter about this, no need to go into it any deeper).

Final modifiers

The fields should be final, as they are not meant to be changed. Non-final fields always increase the cognitive load on the reader as they have to figure out where the fields are modified.

Constructors vs. static factory methods

In this application it could be useful to instantiate the objects with static factory methods.

public abstract class Matryoshka {

    public static Matryoshka of(String name, ...) {
        return new RootMatryoshka(name, ...);
    }

    public static Matryoshka of(String name, ..., Matryoshka innerMatryoshka) {
        Objects.requireNonNull(innerMatryoshka);
        return new OuterMatryoshka(name, ..., innerMatryoshka);
    }
}


Static factory methods allow you to return a different implementations when needed. The root matryoshka would return static values from the methods that calculate weight etc. The outer matryoshkas would simply perform recursion and addition with no need for null checks (as the factory method prevents null values). There are rules on how classe that use static factory methods should be written, I won't replicate them here.

But that's pretty much a matter of taste. The current implementation is just fine too.

Bugs

If the root matryoshka wears a babushka, the calculation returns an incorrect answer.

Style

I find the unnecessary use of this distracting. In my opinion it should be used only when there is a naming conflict. When done so, the number of references to this can be used as a metric for bad naming or problematic structure.

Tail recursion

Since you asked about efficiency, I have to talk about tail recursion. But be aware that this all is total and complete premature optimization. Each of the recursive methods could be replaced with a loop, which would eliminate the need for populating the stack on each recursion:

public int howManyDolls() {
    int dollCount = 0;

    Matryoshka currentDoll = this;
    while (currentDoll != null) {
        dollCount++;
        currentDoll = getInnerDoll();
    }
    return count;
}


It probably won't affect running time, but at least you're not limited by the stack size. You can have millions of matryoshkas! But you will fail the recursion task, since now this has none.