我可以在swift中使用协议支持多重继承吗? [英] Can i able to support multiple inheritance with protocol in swift?

查看:353
本文介绍了我可以在swift中使用协议支持多重继承吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在Swift中,通过使用扩展,您可以在协议中提供方法体。在我的代码中,我能够给出方法体,参见

  protocol Test1 {
func display()
}
扩展名Test1 {

func display(){
print(display Test1)
}
}

协议Test2 {
func display()
}
扩展名Test2 {

func display(){
print(display Test2)
}
}
类ViewController:UIViewController,Test1,Test2 {

var test1:Test1?
var test2:Test2?

func display(){
print(display)
}

override func viewDidLoad(){
super.viewDidLoad( )
//加载视图后进行任何其他设置,通常是从笔尖。

self.test1 = self
test1?.display()

self.test2 = self
test2?.display()
}

覆盖func didReceiveMemoryWarning(){
super.didReceiveMemoryWarning()
//处置可以重新创建的任何资源。
}
}

我知道我给了test1和test2对象的地址ViewController类。所以显示被打印两次。但在协议中,我能够使用这些方法。



所以我的问题是为什么苹果给我在协议中编写方法体的功能?



可以有谁帮我理解这个功能?

解决方案

虽然问题看起来很简单,但解释了面向协议编程的所有方面以及外出的重要性将让我围绕它编写完整的博客:)



无论如何,面向协议的编程基本上使您能够利用多重继承,如JAVA,Objective-C赢得了面向对象的编程语言由于 DiamondProblem 支持



现在虽然面向协议编程允许您将功能
/功能建模为协议而不是类的实例方法(如目标C的情况),但我们必须同意我们都喜欢继承!!,记住你曾经宣布过一次见面hod与一些操作,然后扩展它写任何特定的孩子,仍然使用父方法中的所有代码只需通过调用super.methodname ???现在你怎么可能在协议中实现它?你不能重新使用代码??



所以Protocols默认实现是向类提供默认实现的简单方法,它只是想扩展和确认协议但不打扰修改它。



示例:假设我有一个打印我的姓氏的协议,如果父类确认它,它将打印相同的姓氏作为我,如果我也确认相同的协议:)纠正所有的姓氏后它不会改变!!!



只是因为你确认了你需要的协议如果协议已经有自己的默认实现,则不提供其方法实现。如果你想做除提供的默认实现以外的其他事情,你将提供自己的东西:)

  protocol Test {
func test1()
}

扩展名测试{
func test1(){
print(Yo man)
}
}

协议Test2 {
func test2()
}

扩展名Test2 {
func test2(){
print( 再见男人)
}
}

类ViewController:UIViewController,Test,Test2 {

覆盖func viewDidLoad(){
super.viewDidLoad()
self.test1()
self.test2()
}
}

正如您所看到的,我没有向test1或test2提供任何实现,但我使用它就像它已经为我实现的那样:)



这是默认实现协议的意图。希望它有所帮助



观察:



您有两个协议,Test1和Test2两者都有相同的方法显示,现在你进入DiamondProblem的基本问题,如果我只是调用display()调用哪个实现? Test1或Test2's ?? Swift在编译时解决它并告诉你在调用self.display()时模糊地使用display()



它仍然可能在你的代码中工作的唯一原因是因为你已经创建了两个类型为test1和test2的变量,并且你已经使用test1.display()和test2.display()来调用方法,这些方法没有歧义,但那不是你想要如何使用它不是吗?? / p>

所以基本上你永远不会遇到协议的钻石问题:)


In Swift, with the use of extension you can give method body in "protocol". in my code I am able to give method body, see

protocol Test1{
    func display()
}
extension Test1{

    func display(){
        print("display Test1")
    }
}

protocol Test2{
    func display()
}
extension Test2{

    func display(){
        print("display Test2")
    }
}
class ViewController: UIViewController,Test1,Test2 {

    var test1 : Test1?
    var test2 : Test2?

    func display() {
        print("display")
    }

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.

        self.test1 = self
        test1?.display()

        self.test2 = self
        test2?.display()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
        // Dispose of any resources that can be recreated.
    }
}

I know that I give test1 and test2 object's address in ViewController class. so "display" is printed two times. but in both "protocol" I am able to body of those methods.

so my question is that why apple give me functionality to write methods body in "protocol" ?

Can anyone help me to understand this functionality ?

解决方案

Though the question looks simple explaining all the aspects of Protocol Oriented Programming and importance of out will make me write whole blog around it :)

Anyway, Protocol Oriented Programming basically enables you to exploit the multiple inheritance which Object Oriented Programming languages like JAVA, Objective-C won't support because of DiamondProblem

Now though Protocol Oriented Programming allows you to model the capability /functionality as a protocol rather than as instance method of classes (as in case of Objective C) we have to agree that we all enjoyed Inheritance always!!, Remember you used to declare a method with some operation and then extend it write whatever specific to child and still use all the code in parent method simply by calling super.methodname??? Now how can you possibly achieve it in protocol ??? You can't re use the code ??

So Protocols default implementations are the simple ways to provide the default implementation to the classes, which simply wants to extend and confirm the protocol but does not bother to modify it.

Example : Assume I have a protocol which prints my family name, if parent class confirms to it it will print same family name as me if I confirm to same protocol as well :) Correct after all its a family name it won't change!!!

Just because you confirm to a protocol u need not provide its methods implementation if the protocol already has its own default implementation. You will provide your own if you want to do something other than the default implementation provided :)

protocol Test {
    func test1()
}

extension Test {
    func test1() {
        print("Yo man")
    }
}

protocol Test2 {
    func test2()
}

extension Test2 {
    func test2() {
        print("Bye man")
    }
}

class ViewController: UIViewController,Test,Test2 {

    override func viewDidLoad() {
        super.viewDidLoad()
        self.test1()
        self.test2()
    }
}

As you can see I have not provided any implementation to test1 or test2 yet I use it as if its already implemented for me :)

Thats the intention of default implementation of protocol. Hope it helps

Observation:

You have two protocols, Test1 and Test2 both have same method display, now you are getting into the fundamental issue of DiamondProblem, if I simply call display() which implementation to call ?? Test1's or Test2's ?? Swift solves it at compile time and tells you that ambiguous use of display() when you call self.display()

The only reason its still working probably in ur code because you have created two variables of type test1 and test2 and you have called methods using test1.display() and test2.display() which is ok no ambiguity there, but thats not how you want to use it isn't it ??

So basically you can never get into Diamond problem with Protocols :)

这篇关于我可以在swift中使用协议支持多重继承吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆