-2

Objective-с doesn't have built-in method visibility like protected, private, abstract. How to implement it like in Java?

Solution in my answer below

abuharsky
  • 1,151
  • 12
  • 21
  • possible duplicate of [Creating an abstract class in Objective C](http://stackoverflow.com/questions/1034373/creating-an-abstract-class-in-objective-c) – Cyrille Mar 17 '14 at 12:59

1 Answers1

0

private method visibility - easily implemented inside .m files:

@interface SomeClass () <SomeProtocolForPrivateImplementation>
{
    int _someVar1;
    int _someVar2;
    int _someVarN;
}
@property (nonatomic, readwrite) NSString *someProperty;

- (void)_somePrivateMethod;

@end

@implementation SomeClass

- (void)_somePrivateMethod
{
}

@end

protected and abstract method visibilities require Class Category, but it's not only one solution. You can use next model. For example you have abstract Data Model class which implements the basic mechanisms for working with some data, for example some synchronization. You need to create subclasses that will load the data in different ways. In java you can easily make it like this:

public abstract class AbstractDataModel
{
    public abstract String getDataModelID();

    protected void syncData()
    {
    // ... some data synchronization
    }
}
public class DataModel extends AbstractDataModel
{

    @Override
    public String getDataModelID() {
        // TODO Auto-generated method stub
        return null;
    }

}

But you can't do the same in Objective-сб you need to use Class Categories, it no so cool :( . I found a way to do this in more elegant way using protocols:

In .h file:

    @protocol ModelSubclassingProtocol;
    @interface Model : NSObject
    {
        int _someVar;
    }

    @property (nonatomic, readonly) NSString *someProperty;

    - (id)initWithDictionary:(NSDictionary*)info;
    - (BOOL)updateFromDictionary:(NSDictionary*)info; // return TRUE if update has changes
    - (void)reloadItems;

    @end



    // use protocol for subclasses
    @protocol ModelSubclassingProtocol <NSObject>

    @required
    // all abstract methods here
    - (Class)someAbstractMethod1;
    + (NSString*)someAbstractMethod2;
    - (BOOL)someAbstractMethod3;

@optional
// all protected methods here
- (void)someProtectedMethod1;
- (BOOL)someProtectedMethod2;

    @end

In .m file:

#define SUBCLASS ((id<ModelSubclassingProtocol>)self)

@interface Model () <SomeProtocolsForPrivateImplementation>
{
    NSMutableArray  *_somePrivateVar1;
}
@property (nonatomic, readwrite) NSString *someProperty1;

@end

@implementation RDModel

+ (id)alloc
{
    // check subclassing protocol implementation
    Protocol    *protocol       = @protocol(ModelSubclassingProtocol);

    NSString    *protocolName   = NSStringFromProtocol(protocol);
    NSString    *className      = NSStringFromClass(self.class);

    NSAssert([self.class conformsToProtocol:protocol], @"\n\nERROR: \"%@\" must be conforms to protocol \"%@\".\nRecommended to use internal class extension in \"%@.m\", sample code:\n\n@interface %@ () <%@>\n@end\n\n", className, protocolName, className, className, protocolName);

    return [super alloc];
}

#pragma mark - Private

- (NSDictionary*)_synchronizeItems:(NSArray *)array
{
//... some implementation before

// use abstract methods here
        NSString *itemIdentifier = [SUBCLASS itemIdentifier];

//... some implementation after
}

Sorry for bad english.

abuharsky
  • 1,151
  • 12
  • 21
  • I don't see in which way your methods are protected ? – Tancrede Chazallet Mar 17 '14 at 13:11
  • You can protect methods visibility using protocol, that implemented only by subclasses. – abuharsky Mar 17 '14 at 14:24
  • The problem of this approach on abstract methods is that you have no strong linking between those methods and the abstract super class. If you really want to mimic other languages and use polymorphism over any of those abstract methods, you will "need" an object of the protocol type: the super class itself does not implement the protocol and has no reference to those methods at all. I wrote *"need"* because you *can* actually call any method on any object, as Objective-C uses a "message sending" rather than a "method invocation" pattern. – Gobe May 06 '16 at 22:36
  • Abstract class could privately implement the protocol in a private.h, then subclasses could import the private header in their .m. Then subclasses can call super methods. – malhal Dec 21 '17 at 09:07