1

I am writing the Objective C class similar to the C# Abstract class. I need to assign BOOL variables to TRUE in abstract class implementation. As i know in Objective C for Abstract class there wont be init method. So how can i change my BOOL variable default value to TRUE?

C# Class:

public abstract class ABC
{
      private bool isNew = true;
}

How can i implement the same in Objective C?

Cintu
  • 913
  • 2
  • 16
  • 32
  • you should override init method in your class. http://stackoverflow.com/questions/10704291/where-should-i-initialize-variables-in-objective-c – stosha Oct 21 '13 at 07:18
  • You can also reverse the sense of your variable, so it can default to NO. For example, `isOld` instead of `isNew`. Otherwise, override `-init` as others suggest. – nielsbot Oct 21 '13 at 07:27
  • @nielsbot Do you really need to add a comment saying you've added an answer? – Abizern Nov 14 '13 at 13:03

3 Answers3

4

First, Objective-C does not have the concept of abstract classes as such, you just create a class you do not intend to make instances of. So the "abstract" nature is not enforced by the compiler (though you can choose to enforce it in code if that is really required).

So an "abstract" is just a class, and it can have an init method - and that is what you will need to set default values for instance variables.

CRD
  • 52,522
  • 5
  • 70
  • 86
  • I referred this blog for implementing abstract class http://iphonesdkbasics.blogspot.in/2010/01/abstract-classes-in-objective-c.html - In this `[self doesNotRecognizeSelector:_cmd];` is there in init method. Is it wrong implementation? – Cintu Oct 21 '13 at 07:26
  • 1
    Seems heavy handed to me.. I wouldn't even bother enforcing the "don't instantiate me" rule, just have a note in the header file instead. "hey, don't instantiate this class". If you really want to enforce the abstractness of a class, instead add the following to your `-init` method: `if ( [ self class ] == [ MyAbstractClass class ] ) { @throw ...don't instantiate MyAbstractClass exception... ; }` – nielsbot Oct 21 '13 at 07:30
  • @nielsbot - If i wont instantiate then how can i change my variables default value? – Cintu Oct 21 '13 at 07:35
  • @Cintu - an abstract class is not instantiated *directly*, only subclasses derived from it are instantiated. As part of `init` of any class you invoke the `init` of the superclass - this is when the `init` of the abstract method is invoked and sets the default values for the instance variables. – CRD Oct 21 '13 at 07:49
  • @Cintu - there are various approaches to producing "abstract" classes - from the simple one of simply not instantiating the class to heavy weight solutions. Take a look at [this answer](http://stackoverflow.com/questions/13793864/abstract-class-for-objective-c/13797335#13797335) for a medium weight solution. – CRD Oct 21 '13 at 07:54
  • @CRD - I have understood the concept of abstract class now. I have implemented same as nielsbot answer. But my subclass of ABC is not able to read the assigned value. `isNew = YES;` – Cintu Oct 21 '13 at 09:42
  • If you are trying to access an instance variable then they default to private access. To allow a subclass to access an instance variable you should proceed the definitions with `@protected`. If you follow @nielsbot and use a *property* then the subclass can access it. – CRD Oct 21 '13 at 10:00
3

Here's how you can have an "abstract" class that also initializes non-nil member vars:

// ABC is an abstract class--not to be instantiated directly, but subclassed

@interface ABC : NSObject
@property ( nonatomic ) BOOL isNew ;
@end

@implementation ABC
-(id)init
{
    self = [ super init ] ;

    if ( [ [ self class ] isEqual:[ ABC class ] ] )
    {
        @throw [ NSException exceptionWithName:NSGenericException reason:@"Warning: class ABC must be subclassed. Cannot directly create instances of class ABC" userInfo:nil ] ;
        return nil ;
    }

    self.isNew = YES ;

    return self ;
}

@end

Your subclass would look like this:

@interface MyConcreteABCSubclass : ABC
@end

@implementation MyConcreteABCSubclass

-(id)init
{
    self = [ super init ] ;
    if ( self )
    {
        // initialize subclass vars
    }
    return self ;
}

//
// ... your subclass methods go here ...
//

@end
nielsbot
  • 15,922
  • 4
  • 48
  • 73
  • Ok, I think it's better to throw an exception since this would be a coding error. – nielsbot Oct 21 '13 at 09:28
  • thanks. I am doing the same now. In the subclass of ABC i have added `ABC *obj;` `if (obj.isNew) {` `NSLog(@"NEW");` `}` `else{` `NSLog(@"OLD");` `}` But it is not taking the value isNew = YES. It is printing as OLD – Cintu Oct 21 '13 at 09:37
  • did you remember to call `[super init]` in your subclass? if your code is in a subclass method, use `self.isNew` – nielsbot Oct 21 '13 at 16:46
  • Did you instantiate the instance of your ABC subclass? there's no default constructor or anything like that in ObjC. declaring a variable of type" ABC*" , you need to do this: `ABC * obj = [[MyABCSubclass alloc] init]` – nielsbot Oct 21 '13 at 16:50
  • 1
    alloc creates the storage space for an object instance, init initializes the object instance in that space. – nielsbot Oct 21 '13 at 16:52
1

you have to implement init and set all the properties to the value you want

OR

you can implement getters who return default values as long they are not set

Jonathan Cichon
  • 4,396
  • 16
  • 19
  • 1
    you could use `NSNumber numberWithBool:` instead of a BOOL but with primitives implementing `init` is a better approach i think. – Jonathan Cichon Oct 21 '13 at 07:21