I'm working on this Objective C programming assignment I found online.  I'm not sure if I have met all the requirements, especially part C. Any help or suggestion will be appreciated.Part 6a) Implement class A with properties a1, a2, and a3 (int,  string, int).b) New objects are automatically initialized to 1, hello, 1.c) Also provide initializer to any data and constructor (called  without alloc) to do the same.d) Make sure %@ ob object of A will print all data.e) Then implement B inheriting from A. B adds property b (string). f) Make sure B works as A, that is new object is initialized to 1, hello, 1, and 3 (the new data). The rest also must work on B.   //classA.h file#import <Foundation/Foundation.h>@interface ClassA : NSObject// Part 6a@property int a1;@property NSString *a2;@property int a3;-(NSString *) description;-(id) initWithA1: (int) x andA2: (NSString *) s andA3: (int) y;-(id) init;@end//classA.m file#import ClassA.h@implementation ClassA-(id) initWithA1:(int)x andA2:(NSString *)s andA3:(int)y {    self = [super init];    if (self) {        self.a1 = x;        self.a2 = s;        self.a3 = y;    }    return self;}// part 6b- (id) init {    return [self initWithA1:1 andA2:@hello andA3:1];}// part 6d-(NSString *) description {    return [NSString stringWithFormat:@ClassA a1 = %d , a2 = %@ , a3 = %d, self.a1, self.a2, self.a3];}@end//classB.h file#import ClassA.h@interface ClassB : ClassA@property int a1;@property NSString *a2;@property int a3;@property NSString * b;-(NSString *) description;-(id) initWithA1:(int)x andA2:(NSString *)s andA3:(int)y andB: (NSString *) z;-(id) init;@end//classB.m file#import ClassB.h@implementation ClassB-(id) initWithA1:(int)x andA2:(NSString *)s andA3:(int)y andB:(NSString *)z {    self = [super init];    if (self) {        self.a1 = x;        self.a2 = s;        self.a3 = y;        self.b = z;    }    return self;}-(id) init {    return [self initWithA1:1 andA2:@hello andA3:1 andB:@3];}-(NSString *) description {    return [NSString stringWithFormat:@ClassB a1 = %d , a2 = %@ , a3 = %d , b = %@ , self.a1, self.a2, self.a3, self.b];}@end//viewController.m file#import ViewController.h#import ClassA.h#import ClassB.h@interface ViewController ()@end@implementation ViewController- (void)viewDidLoad{    [super viewDidLoad];    ClassA * a = [ClassA new];    NSLog(@%@, a);    ClassB * j = [ClassB new];    NSLog (@%@, j);}- (void)didReceiveMemoryWarning{    [super didReceiveMemoryWarning];    // Dispose of any resources that can be recreated.}@end
Working with Classes (inheriting), @ properties and Initialization
classes;objective c;inheritance
This code does what it is asked to do.  But it can still be better.First of all, in init and factory methods, it is good to use instancetype as the return type rather than id.  instancetype allows you to still return the correct type when you've subclassed, but it doesn't return the generic id that can be assigned to anything.  We want to make sure the IDE can check us some, and instancetype will help it do that.Second, we shouldn't be using and in method names like this.  The word and in method names is used to indicate distinct actions happening.  There's only a single action taking place here, so our method name should look more like this:-(id) initWithA1:(int)x A2:(NSString *)s A3:(int)y B: (NSString *) z;Further more, the parameters names should match.  It should really be:- (instancetype)initWithA1:(int)a1 A2:(NSString *)a2 A3:(int)a3 B: (NSString *)b;Though truly, the variable names should be even better, but this is what the assignment requires, so I'll let it slide.The only other problems I see is that class B doesn't act like a subclass of A at all.  We should use our inheritance.-(id) initWithA1:(int)x andA2:(NSString *)s andA3:(int)y andB:(NSString *)z {    self = [super init];    if (self) {        self.a1 = x;        self.a2 = s;        self.a3 = y;        self.b = z;    }    return self;}There's more available to us then simply [super init];.  How about try this:-(id) initWithA1:(int)x andA2:(NSString *)s andA3:(int)y andB:(NSString *)z {    self = [super initWithA1:x andA2:s andA3:y];    if (self) {        _b = z;    }    return self;}Let's let A's initWith... method take care of the parameters it takes care of and let B just handle the parameters that B adds.Now in B's description method:-(NSString *) description {    return [NSString stringWithFormat:@ClassB a1 = %d , a2 = %@ , a3 = %d , b = %@ , self.a1, self.a2, self.a3, self.b];}Again, we don't make use at all of the fact that we're a subclass.First of, let's make a small change to A's description method, like so:-(NSString *) description {    return [NSString stringWithFormat:@%@ a1 = %d , a2 = %@ , a3 = %d,        [self class], self.a1, self.a2, self.a3];}Now rather than assuming this method has been called for ClassA, we just return the name of the class as the first part of the string.  Now let's improve B:- (NSString *)description {    return [[super description] stringByAppendingFormat:@, b = %@, self.b];}And finally, we can remove the property declarations of a1, a2, and a3 from b's @interface.  They were declared in A, that automatically makes them a part of all of A's subclasses.