Generally speaking, yes: if you want to have your own class, with your own children, then it’s recommended to create your own widget and use GtkBuilder templates to create the composite UI you want.
Because GtkAssistant is a very, very specific type of window, with a lot of assumptions baked into it, unlike GtkWindow and GtkApplicationWindow, or GtkDialog. You may also notice that GtkMessageDialog is not derivable.
The appropriate way to use GtkAssistant—even in GTK3—is to have specific subclasses for each of the pages inside it, instead of a subclass of the top level container. You’re not going to change the behaviour of the Assistant, so there’s no point in creating your own type for it.
Of course, since taking a “final” class and making it derivable is not an ABI break, we can make make some widget classes derivable once again, depending on the amount of requests we get. Since the other way around is not possible without an ABI break, we preferred to start from an appropriate clean slate.
As I said, though, the general approach we recommend is to create your own widget types by starting from a base class and using composite widgets, instead of deriving from a complex widget. This is why we made GtkWidget easier to derive from, compared to GTK2 and GTK3.
The advantage for toolkit maintainers is that the internals of complex widgets stay constrained within the widget, instead of being encoded into the API without possibility of change. This allows us to keep the toolkit API and ABI compatible for longer, and reduces the amount of potential regressions introduced by complex changes.
The advantage for application developers is that they won’t have surprises if a complex widget changes.