Если я правильно понимаю ваш вопрос, возможно, это поможет.
Вы можете дать bark() реализацию по умолчанию, расширив протокол. Тогда на другие классы, которые соответствуют протоколу вы можете изменить реализацию функции коры:
protocol Bark {
func bark()
}
//default implementation
extension Bark {
func bark() { print("Bark") }
}
class Dog: Bark {}
//By calling bark func in Poodle, you change the default implementation.
class Poodle: Dog {
func bark() { print("Yap") }
}
class GermanShephard: Dog {
func bark() { print("Woof") }
}
let dog = Dog()
let poodle = Poodle()
let germanShephard = GermanShephard()
dog.bark()
//Bark
poodle.bark()
//Yap
germanShephard.bark()
//Woof
Вы можете также не делать реализацию каких-либо по умолчанию, и просто добавить свои собственные для каждой ситуации
Edit после комментария:
Это одна из основных причин, по которой протоколы полезны. Они удаляют жесткую связь, связанную с подклассом. Это базовый пример, поскольку во всей теме много информации, но вместо подкласса Dog вы можете сделать протокол DogRepresentable и назначить все привилегии и функции по умолчанию, которые все собаки реализуют одинаково. Тогда вы можете расширить DogRepresentable где самостоятельно: UIViewController и реализовать функциональные возможности по умолчанию:
protocol Barkable {
func bark()
}
protocol DogRepresentable: Barkable {
//properties and functions all dogs will have with same implementation
}
extension DogRepresentable where Self: UIViewController {
//default implementation for functions all dogs will use
}
Назначая Barkable к DogRepresentable, вы знаете, любой класс, который соответствует DogRepresentable также должны соответствовать Barkable.
Теперь, когда вы назначаете DogRepresentable к классу, он получит всю реализацию по умолчанию базового класса будет получить, и вы вынуждены вызвать функцию коры(), чтобы соответствовать протоколу должным образом:
class Dog: DogRepresentable {
func bark() { print("Bark") }
}
class Poodle: DogRepresentable {
func bark() { print("Yap") }
}
class GermanShephard: DogRepresentable {
//Won't conform because it doesn't have bark()
}
Таким образом, вы получаете всю реализацию по умолчанию, как базовый класс, но не должны забывать о переопределении функции суперкласса.
Edit 2 на основе второго комментария:
В этом случае вам лучше всего оставить DogRepresentable, не соответствуя к Barkable, а затем создать протоколы для различных типов: так что если у вас есть собака, которые Яп вы могли бы сделать протокол Yappable который имеет функцию коры и реализацию по умолчанию. Затем вы можете использовать другой протокол Barkable со своей собственной функцией коры и собственную реализацию по умолчанию. Затем совместите класс с протоколом, которому они должны соответствовать. Пудель соответствует Yappable, Собака соответствует Barkable.
Создав эти отдельные протоколы, вы можете сохранить функциональность для каждой ситуации в одном месте и использовать только то, что вам нужно, чтобы ваш код был более чистым, более читаемым и сухим.
Что бы ваш подход для этого быть в Java? Это было бы точно так же, как в Свифте. – Alexander