protocol AnimalProtocol { func a() func c() func d() } extension AnimalProtocol { func a() { print("AnimalProtocol.a") } func b() { print("AnimalProtocol.b") } func c() { print("AnimalProtocol.c") } func d() { defaultD(self) } } func defaultD<X: AnimalProtocol>(_ obj: X) { print("AnimalProtocol.d") } class Animal : AnimalProtocol { func a() { print("Animal.a") } func b() { print("Animal.b") } func d() { defaultD(self) } } class Cat : Animal { override func a() { print("Cat.a") } override func b() { print("Cat.b") } func c() { print("Cat.c") } override func d() { print("Cat.d") } } func invokeA<X: AnimalProtocol>(_ x: X) { x.a() } func invokeB<X: AnimalProtocol>(_ x: X) { x.b() } func invokeC<X: AnimalProtocol>(_ x: X) { x.c() } func invokeD<X: AnimalProtocol>(_ x: X) { x.d() } var cat1: Cat = Cat() invokeA(cat1) invokeB(cat1) invokeC(cat1) invokeD(cat1)