Proper pattern for this would be
# Parent class
extends Node
class_name CustomNode
func _print_something():
print("Hello")
_on_print_something()
# The virtual function extending _print_something()
func _on_print_something():
pass
# Child class
extends CustomNode
func _ready():
_print_something()
func _on_print_something():
print("World")
# Output when Child class is _ready
Hello
World
For deeper hierarkies use composition instead, and you save yourself a lot of work by decoupling responsibilites.