Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift access control on protocol conformance

I have a private protocol defined in a file as below

private protocol testProtocol {
 func testFunc1()
 func testFunc2()
}

A public class conforms to the above protocol as follows

 public class testClass : testProtocol {
 func testFunc1() {}
 func testFunc2() {}
}

As per apples documentation , the members of a public class get internal access control by default unless it is explicitly set to a different access control modifier.

The documentation also says that a type's conformance to a protocol with a lower access control will make the type's implementation of the protocol access control the same as that of the protocol. In this scenario since the type's access control is public and the protocols access control is private , the methods testfunc1 and testfunc2 should get an access control of private.

When the class is instantiated in a different source file and the methods are accessed as below , the compiler does not show an error which is not expected as the methods should be private as per the guidelines

var test: testClass = testClass()
test.testFunc1()

Is this expected behavior ? Am i missing something?

like image 840
Shalini Yadav Avatar asked Sep 30 '15 22:09

Shalini Yadav


2 Answers

According to Apple's documentation:

When you write or extend a type to conform to a protocol, you must ensure that > the type’s implementation of each protocol requirement has at least the same > access level as the type’s conformance to that protocol.

Please be aware of the "at least" in the doc, it means that the as long as the access level of the type's implementation of the protocol requirements is higher or equal to the access level of the protocol, it will be ok. In your case, testFunc1 and testFunc2 from testClass have the default access level of internal, it is higher than access level of private. So actually the two methods in testClass get the access level of internal, and compiler won't treat it as en error.

We can change your code a little bit as follows:

    fileprivate protocol TestProtocol {
        func testFunc1()
        func testFunc2()
    }

    public class TestClass : TestProtocol {
        public func testFunc1() {}
        public func testFunc2() {}
   }

This piece of code will also compile without an error.

like image 120
Matthew An Avatar answered Oct 13 '22 07:10

Matthew An


Apple Documentation says:

When you write or extend a type to conform to a protocol, you must ensure that the type’s implementation of each protocol requirement has at least the same access level as the type’s conformance to that protocol.

According to this I assume that implementing methods testFunc1 and testFunc2 with another access control modifier inside testClass just overrides that from protocol. If you use default protocol implementation of this methods like the following compiler will return error:

extension testProtocol {
    func testFunc1() {}
    func testFunc2() {}
}

As far as Swift is Protocol Oriented Language with replacing inheritance with protocols it's probably reasonable if you want to change protocol defined access level of function inside your custom class.

like image 22
iyuna Avatar answered Oct 13 '22 08:10

iyuna