Create an account

Very important

  • To access the important data of the forums, you must be active in each forum and especially in the leaks and database leaks section, send data and after sending the data and activity, data and important content will be opened and visible for you.
  • You will only see chat messages from people who are at or below your level.
  • More than 500,000 database leaks and millions of account leaks are waiting for you, so access and view with more activity.
  • Many important data are inactive and inaccessible for you, so open them with activity. (This will be done automatically)


Thread Rating:
  • 702 Vote(s) - 3.44 Average
  • 1
  • 2
  • 3
  • 4
  • 5
Creating an abstract class in Objective-C

#11
The answer to the question is scattered around in the comments under the already given answers. So, I am just summarising and simplifying here.

#Option1: Protocols#
If you want to create an abstract class with no implementation use 'Protocols'. The classes inheriting a protocol are obliged to implement the methods in the protocol.

@protocol ProtocolName
// list of methods and properties
@end

#Option2: Template Method Pattern#
If you want to create an abstract class with partial implementation like "Template Method Pattern" then this is the solution.

[To see links please register here]

Reply

#12
Can't you just create a delegate?

A delegate is like an abstract base class in the sense that you say what functions need to be defined, but you don't actually define them.

Then whenever you implement your delegate (i.e abstract class) you are warned by the compiler of what optional and mandatory functions you need to define behavior for.

This sounds like an abstract base class to me.
Reply

#13
I usually just disable the init method in a class that I want to abstract:

- (instancetype)__unavailable init; // This is an abstract class.

This will generate an error at compile time whenever you call init on that class. I then use class methods for everything else.

Objective-C has no built-in way for declaring abstract classes.
Reply

#14
Changing a little what @redfood suggested by applying @dotToString's comment, you actually have the solution adopted by Instagram's [IGListKit][1].

1. Create a protocol for all the methods that make no sense to be defined in the base (abstract) class i.e. they need specific implementations in the children.
2. Create a base (abstract) class that *does not* implement this protocol. You can add to this class any other methods that make sense to have a common implementation.
3. Everywhere in your project, if a child from `AbstractClass` must be input to or output by some method, type it as `AbstractClass<Protocol>` instead.

Because `AbstractClass` does not implement `Protocol`, the only way to have an `AbstractClass<Protocol>` instance is by subclassing. As `AbstractClass` alone can't be used anywhere in the project, it becomes abstract.

Of course, this doesn't prevent unadvised developers from adding new methods referring simply to `AbstractClass`, which would end up allowing an instance of the (not anymore) abstract class.

Real world example: [IGListKit][1] has a base class `IGListSectionController` which doesn't implement the protocol `IGListSectionType`, however every method that requires an instance of that class, actually asks for the type `IGListSectionController<IGListSectionType>`. Therefore there's no way to use an object of type `IGListSectionController` for anything useful in their framework.


[1]:

[To see links please register here]

Reply

#15
From the [Omni Group mailing list][1]:

Objective-C doesn't have the abstract compiler construct like Java at
this time.

So all you do is define the abstract class as any other normal class
and implement methods stubs for the abstract methods that either are
empty or report non-support for selector. For example...

- (id)someMethod:(SomeObject*)blah
{
[self doesNotRecognizeSelector:_cmd];
return nil;
}

I also do the following to prevent the initialization of the abstract
class via the default initializer.

- (id)init
{
[self doesNotRecognizeSelector:_cmd];
[self release];
return nil;
}

[1]:

[To see links please register here]

Reply

#16
No, there is no way to create an abstract class in Objective-C.

You can mock an abstract class - by making the methods/ selectors call doesNotRecognizeSelector: and therefore raise an exception making the class unusable.

For example:

- (id)someMethod:(SomeObject*)blah
{
[self doesNotRecognizeSelector:_cmd];
return nil;
}

You can also do this for init.
Reply

#17
The solution I came up with is:

1. Create a protocol for everything you want in your "abstract" class
2. Create a base class (or maybe call it abstract) that implements the protocol. For all the methods you want "abstract" implement them in the .m file, but not the .h file.
3. Have your child class inherit from the base class AND implement the protocol.

This way the compiler will give you a warning for any method in the protocol that isn't implemented by your child class.

It's not as succinct as in Java, but you do get the desired compiler warning.
Reply

#18
In fact, Objective-C doesn't have abstract classes, but you can use **Protocols** to achieve the same effect. Here is the sample:

###CustomProtocol.h

#import <Foundation/Foundation.h>

@protocol CustomProtocol <NSObject>
@required
- (void)methodA;
@optional
- (void)methodB;
@end

###TestProtocol.h

#import <Foundation/Foundation.h>
#import "CustomProtocol.h"

@interface TestProtocol : NSObject <CustomProtocol>

@end

###TestProtocol.m

#import "TestProtocol.h"

@implementation TestProtocol

- (void)methodA
{
NSLog(@"methodA...");
}

- (void)methodB
{
NSLog(@"methodB...");
}
@end

Reply

#19
[Cocoa][1] doesn’t provide anything called abstract. We can create a class abstract which gets checked only at runtime, and at compile time this is not checked.

[1]:

[To see links please register here]

Reply

#20
If you are used to the compiler catching abstract instantiation violations in other languages, then the Objective-C behavior is disappointing.

As a late binding language it is clear that Objective-C cannot make static decisions on whether a class truly is abstract or not (you might be adding functions at runtime...), but for typical use cases this seems like a shortcoming. I would prefer the compiler flat-out prevented instantiations of abstract classes instead of throwing an error at runtime.

Here is a pattern we are using to get this type of static checking using a couple of techniques to hide initializers:

//
// Base.h
#define UNAVAILABLE __attribute__((unavailable("Default initializer not available.")));

@protocol MyProtocol <NSObject>
-(void) dependentFunction;
@end

@interface Base : NSObject {
@protected
__weak id<MyProtocol> _protocolHelper; // Weak to prevent retain cycles!
}

- (instancetype) init UNAVAILABLE; // Prevent the user from calling this
- (void) doStuffUsingDependentFunction;
@end

----------

//
// Base.m
#import "Base.h"

// We know that Base has a hidden initializer method.
// Declare it here for readability.
@interface Base (Private)
- (instancetype)initFromDerived;
@end

@implementation Base
- (instancetype)initFromDerived {
// It is unlikely that this becomes incorrect, but assert
// just in case.
NSAssert(![self isMemberOfClass:[Base class]],
@"To be called only from derived classes!");
self = [super init];
return self;
}

- (void) doStuffUsingDependentFunction {
[_protocolHelper dependentFunction]; // Use it
}
@end

----------

//
// Derived.h
#import "Base.h"

@interface Derived : Base
-(instancetype) initDerived; // We cannot use init here :(
@end

----------

//
// Derived.m
#import "Derived.h"

// We know that Base has a hidden initializer method.
// Declare it here.
@interface Base (Private)
- (instancetype) initFromDerived;
@end

// Privately inherit protocol
@interface Derived () <MyProtocol>
@end

@implementation Derived
-(instancetype) initDerived {
self= [super initFromDerived];
if (self) {
self->_protocolHelper= self;
}
return self;
}

// Implement the missing function
-(void)dependentFunction {
}
@end

Reply



Forum Jump:


Users browsing this thread:
1 Guest(s)

©0Day  2016 - 2023 | All Rights Reserved.  Made with    for the community. Connected through