Superclass vs Protocol in Swift? - swift

I've never worked with objective C but have a fair bit of experience with C++.
What exactly is the difference between a superclass and a protocol in objective C? I read that a protocol is essentially a pure virtual class, but is that it? Is a protocol simply a specific type of superclass?

A protocol is a contract a class is going to conform to. When a class conforms to a protocol it tells the compiler that it will implement all the methods and all the properties declared in the protocol.
In Objective-C the class additionally needs a superclass. In a lot of cases this is NSObject. The superclass implements already a lot of methods (like isEqual:). A protocol never implements any methods or defines any property.

A protocol tells which properties/operations a class must implement. A superclass implements them and you can add your own stuff on top.

A protocol defines a set of method definitions that a class or struct must implement, very much like a Java interface.
A superclass is the class from which a given class inherits its method definitions, the implementation for those methods, and the instance and class properties.

Related

access control on protocol implementation init

Trying to enforce an access control for a protocol that will be implemented by a singleton class.
I would like the class to have a fileprivate init, is there a way to enforce this behaviour?
Since a protocol is not a class i cannot put the init in the protocol extension.
According to Apple docs:
The access level of each requirement within a protocol definition is automatically set to the same access level as the protocol. You cannot set a protocol requirement to a different access level than the protocol it supports. This ensures that all of the protocol’s requirements will be visible on any type that adopts the protocol.
Link Protocol docs
EDIT: I have misread the question a bit.
If I understood OP's clarification, the only way I know at the moment to ensure that class is singleton is to mark its init method as private or fileprivate.
For my simple singleton with only static methods I have this:
private init() {
}

Protocol with default implementation in swift. Is it interface or abstract class according to OOP?

According to oop, interface describe methods which inherited classes should implement. It can not contains implementations and hasn't state (variables). In swift we have 'protocol'. If protocol hasn't extension with default implementation it mean that it is interface. But if it has default implementation, is it mean that now it is abstact class or it is interface ?

Calling protocol methods on super

Can I call a protocol method from a child on its super class, even though the super class supports the protocol privately?
Let's say I have a Class A which privately conforms to UIGestureRecognizerDelegate protocol. Class B inherits from Class A but when I tried to call [super gestureRecognizerShouldBegin:gestureRecognizer]; I get an error.
Any idea?
The UIScrollViewDelegate doesn't declare a method named gestureRecognizerShouldBegin:gestureRecognizer:.
But generally speaking, yes, its possible to call methods declared in protocols that the super class implements, but keep in mind that methods marked with #optional in the protocol aren't guaranteed to be implemented (you can check this via the respondsToSelector: method)

What does id<Litigating> mean?

I know "id" type, but what does id<Litigating> mean ?
#protocol Litigating
-(int) sue:( id<Litigating> ) someone;
#end
Think of Objective-C protocols as Java, C#, etc. Interfaces on speed.
This is a variable of any class, conforming to the protocol Litigation (this is as far as traditional OOP goes without jumping hoops):
id<Litigation> someone;
This is a variable of the class Company (and subclasses), that also conforms to Litigation:
Company<Litigation>* someone;
This is a variable of class Company, that also conforms to both Litigation and NSCopying**:
Company<Litigation, NSCopying>* someone;
id<SomeProtocol>
implies that this object implements SomeProtocol. It must be implementing all the required methods belonging to SomeProtocol.
It means that the parameter is not only of type id but also conforms to the Litigating (formal) protocol, cf. The Objective-C Programming Language.

Is it good style to declare methods in .h when they're intended to be overwritten by subclass?

I have a class which is intended to be abstract. This means: When someone subclasses it, a few methods MUST be overwritten.
But on the other hand, those methods are not intended to be called manually from anywhere except inside the abstract class (the superclass of the subclass).
Must I declare these methods in .h anyways or can I just add comments in .h which say "you must overwrite -foo and -bar"? Or is there a better pattern to make abstract methods?
Related: Is there a way to create an abstract class in Objective C?
Objective-C doesn't actually have a way to declare a class as abstract. From Apple's Docs:
Abstract Classes
Some classes are designed only or
primarily so that other classes can
inherit from them. These abstract
classes group methods and instance
variables that can be used by a number
of different subclasses into a common
definition. The abstract class is
typically incomplete by itself, but
contains useful code that reduces the
implementation burden of its
subclasses. (Because abstract classes
must have subclasses to be useful,
they’re sometimes also called abstract
superclasses.)
Unlike some other languages,
Objective-C does not have syntax to
mark classes as abstract, nor does it
prevent you from creating an instance
of an abstract class.
The NSObject class is the canonical
example of an abstract class in Cocoa.
You never use instances of the
NSObject class in an application—it
wouldn’t be good for anything; it
would be a generic object with the
ability to do nothing in particular.
The NSView class, on the other hand,
provides an example of an abstract
class instances of which you might
occasionally use directly.
Abstract classes often contain code
that helps define the structure of an
application. When you create
subclasses of these classes, instances
of your new classes fit effortlessly
into the application structure and
work automatically with other objects.
So to answer your question, yes, you need to place the method signature in the header, and should implement the method in the base class such that it generates an error if called, like the related question's answer states.
You can also use a protocol to force classes to implement certain methods.
However you choose to implement the base class, clearly document in the header, as well as in your documentation, exactly what the class assumes and how to go about sub-classing it correctly.
Whenever possible write your code so that improper implementations fail to compile. If you cannot do that then you should try to generate a runtime error (at the very least in a debug build) if the subclass is not written correctly. Do not rely on comments because people will not read them.
You must declare your "protected" and "abstract" methods in a header file, but you can use separate categories to clearly indicate their purpose and intended use.
#interface MyBaseClass : NSObject {
}
- (void)foo;
#end
#interface MyBaseClass(ProtectedMethods)
- (void)bar;
#end
#interface MyBaseClass(AbstractMethods) // Subclasses must implement
- (void)internalBar;
#end
You can put everything in a single header, or you could put your protected and abstract declarations in a separate "protected" header, say MyClassProtected.h, meant to be included only by your subclass implementations. It depends on how badly you want "hide" your protected methods.
Your base class can log, assert, or throw when an abstract/pure-virtual method is called.
As other people have said, Objective-C does not support pure virtual classes.
You can enforce pure virtual behaviour at runtime though. The cleanest way to do this is by using the Objective-C runtime's _cmd and NSObject's -doesNotRecognizeSelector:
- (void)iMustBeImplementedInaSubclass;
{
[self doesNotRecognizeSelector:_cmd]; // Pure virtual
}
As ben says you are probably better served by using a protocol to get your API design right.