Three basic features of “Objective-C base”: encapsulation, inheritance, polymorphism

As we all know, there are three main characteristics of the class in object oriented programming: inheritance, encapsulation, polymorphism, and these three characteristics are the problems that must be understood when learning class, which is the foundation and should be paid more attention to.

Package (Encapsulation)

Packaging is the protection of some of the fields and methods in a class, not to be access to the outside world, has the ability to control a power, there are four kinds of access modifiers in Java: public, default, protected, private, their access permissions are decreased, so that when we define a class, which fields and methods want to expose out, which fields and methods can be exposed, can be distinguished by different modifiers, this is the package.


#import @interface Car: NSObject {/ / this attribute is foreign confidential is equivalent to private, so we need the external access, the default method / definition of get/set must be private, but we can use the @public attribute set to public, then you can directly access the external: person-> capcity = 2.8; / / of course, we usually don't use, because it will destroy the encapsulation, permission / / this is the equivalent of the C usage structure in the body of a total of four kinds: @public, @protected, @private, @package, rights in turn decreases, and the Java is the same as @public float _capcity; / / oil} - (void) run attribute @end;

Here we can see that there are also four types of permissions modifiers in OC: @public, @protected, @private, and @package

The default modifier is @private.

However, it is important to note that the method in OC is not the concept of modifiers, which is different from other languages, and is generally publicly accessible, that is, public. In OC, if you need to make a method is not accessible to the outside world, only need to implement this method in the.M file, not defined in the map document, in short, is the method of realization is not defined, so when the header file into the outside world, this is not a method, the the method can only be used in your.M file.

Two, inherit

Inheritance is an important feature in a class that avoids writing duplicate code and is highly reusable, the purpose of inheritance is to reduce code redundancy, or DRY repeat yourself (don`t).

In Car.h, two attributes and some methods are defined in the Car class:

#import @interface Car: NSObject{NSString *_brand; NSString *_color;} - (void) setBrand: (NSString * Brand); - (void) setColor: (NSString * color); - (void) - (void) brake; quicken; @end

In the Car.m method:

#import "Car.h" @implementation Car (void) setBrand: (NSString * brand{) _brand = brand;} - (void) setColor: (NSString * color{) _color = color;} - (void) brake{NSLog (@ "brake");} - (void) quicken{NSLog (@ "speed"); @end}

In its subclass Taxi, we can inherit the methods of Car.

In the Taxi.h file:

#import "Car.h" @interface Taxi: Car{NSString *_company;} / / company / / print invoices - (void) printTick; @end

The Taxi class inherits the parent class Car, where you need to import the header file of the parent class, and then you have more than one attribute and method in the Taxi class, and the method that matches the parent class inherits or rewrites.

In the Taxi.m file:

#import "Taxi.h" @implementation Taxi (void) printTick{[super brake]; [self brake]; NSLog (@ "% @ taxi print invoices, company: Color:% @% @," _brand, _company, _color, @end);}

For the implementation of the method, here we see that the implementation file does not need to import the header file of the parent class Car because it can be assumed that the Taxi.h header file already contains the header file of the Car. But here, you can use the super keyword to call the superclass method, and here we also can use the self keyword to call, see here actually these two ways of calling the effect is the same, when we re implement the brake method in the subclass (re concept written in Java), then call the super keyword is the parent class method, and the self call is to rewrite after the brake method. Similarly, we can also use attributes in the parent class.

Look at another sub – class, Truck:

In Truck.h:

#import "Car.h" Car @interface Truck / / truck class: Car{float _maxWeight;} / / / / maximum loading method covering the superclass subclass of brake / / priority call - (void) - (void) brake; unload; @end

Here you define a brake method that will override the brake method in the parent class.

In Truck.m:

#import "Truck.h" @implementation Truck (void) brake{[super brake]; NSLog (@ Truck class brake ");} - (void) unload{[super brake]; / / call the superclass method [self brake]; / / can be NSLog (@"% @ the unloading trucks, cargo volume:%.2f the color of the car: "_brand,% @ _maxWeight, _color);} @end

As you can see here, we’ll call the brake method of the parent class in the brake method, and then implement our own logical code.

Three, polymorphism

Polymorphism is really important for object oriented individuals, and it also plays an important role in the elegant way of writing code. In many design patterns are used in most of the polymorphic characteristics, polymorphism characteristics in Java use is very convenient, but C++ is difficult, in fact, that is: the definition of polymorphic type and the actual type is generally based on the form of the interface.

Take the printer as an example:

Write an abstract printer class, Printer,


#import, @interface, Printer: NSObject - (void) print; @end


#import "Printer.h", @implementation Printer - - (void) print{NSLog (@ printer print paper);} @end

Implementation is also very simple, below see specific subclass ColorPrinter:


#import "Printer.h" / / modify the superclass behavior of @interface ColorPrinter printing: Printer - (void) print; @end ColorPrinter.m


#import "ColorPrinter.h", @implementation ColorPrinter - (void) print{NSLog (@ color printer);} @end

Look at the other sub class:


#import "BlackPrinter.h", @implementation BlackPrinter - (void) print{NSLog (@ black and white printer);} @end

Here, we are defining a Person class for handling specific printers.


#import "Person.h" @implementation Person / * - (void) printWithColor: (ColorPrinter *) colorPrint{[colorPrint print];} - (void) printWithBlack: (BlackPrinter *) blackPrint{[blackPrint print];} * / - (void) doPrint: (Printer *) printer{[printer print] @end;}

Check the test code again:


#import "Person.h" @implementation Person / * - (void) printWithColor: (ColorPrinter *) colorPrint{[colorPrint print];} - (void) printWithBlack: (BlackPrinter *) blackPrint{[blackPrint print];} * / - (void) doPrint: (Printer *) printer{[printer print] @end;}


#import "Person.h" #import "BlackPrinter.h" #import "ColorPrinter.h" int main (int argc, const charchar * argv[]) {@autoreleasepool {Person *person =[[Person alloc] init]; ColorPrinter *colorPrint = [[ColorPrinter alloc] init]; BlackPrinter *blackPrint = [[BlackPrinter alloc] init]; / / Printer / * *p1 polymorphism definition = [[ColorPrinter alloc] init]; Printer *p2 = [[BlackPrinter alloc] init] [person doPrint:p1]; [person; doPrint:p2]; * / / / through the console commands to control the use of int CMD do{scanf which printer; (%d, & CMD); if (CMD = = 1) { [person doPrint:colorPrint];}else if (CMD = = 2) {[person doPrint:blackPrint]};}while (1) return 0;}};

The following is to discuss the benefits of polymorphism in the above example, a color printer and a color printer, a printing operation method in the Person class, of course, this method is the need to the printer object, if not true polymorphism (Person.h part of the code in the notes), the two way is to separate the printer the definition of operation, and then in the Person.m (code part of the notes) with specific printer object operation, we see in the main.m file, when person need to use the printer which, to call the specified method:

[person printWithBlack:blackPrint] [person printWithColor:colorPrint]; / / call color printer color printer; / / call

If we need another printer now, then we need to define a way to operate the printer in Person.h, then, if we add a new printer later? Do you want to continue adding methods? Then the Person.h file becomes bloated. So polymorphism now shows the advantage. Using the parent class type defines a method in the Person.h – (void) doPrint: (Printer *) printer; that’s fine. As you can see, the parameter type of this method is the parent class type, and the actual type is a subclass type. The method body is:

- - (void) doPrint: (Printer *) printer{, [printer, print];}

Calling the print method here is the actual type of print method that is passed in.

Printer *p1 = [[ColorPrinter alloc] init]; Printer *p2 = [[BlackPrinter; alloc] init]; [person doPrint:p1]; [person doPrint:p2];

The type on the P1 and P2 surfaces here is printer, but the actual types are subclass types, so call their own corresponding print methods.