Three major features of Objective-C: encapsulation, inheritance, and polymorphism

Three major features of Objective-C: encapsulation, inheritance, and polymorphism

We all know that classes in object-oriented programming have three major characteristics: inheritance, encapsulation, and polymorphism. This is also a topic that must be mentioned when introducing classes. So today, let's take a look at the three major characteristics of classes in OC:

1. Packaging

Encapsulation is to protect some fields and methods in a class from being accessed by the outside world. It has a permission control function. There are four access permission modifiers in Java:

public, default, protected, private

Access rights decrease in order, so when we define a class, which fields and methods do not want to be exposed, which fields and methods can be exposed, can be done through modifiers, this is encapsulation, let's take a look at an example:

Car.h

// Car.h
// 05_ObjectDemo
//
  // Created by jiangwei on 14-10-11.
  // Copyright (c) 2014 jiangwei. All rights reserved.
//

#import

     @interface Car : NSObject{
//This property is kept confidential and is equivalent to private, so if we need to access it externally, we must define get/set methods
//The default is private, but we can use @public to set it as a public attribute, so it can be directly accessed externally: person->capcity = 2.8;
//Of course, we generally don't use it this way, because it will destroy the encapsulation. This usage is equivalent to the permissions in the structure in C
//There are four types: @public, @protected, @private, @package, which are the same as in Java
@public
float _capcity; //Oil volume attribute
}

- (void)run:(float)t;

@end

Here we can see that there are also four access rights modifiers in OC:

@public, @protected, @private, @package

The default modifier is @private

But it should be noted here that there is no concept of modifiers for methods in OC, which is very different from Java. Generally, methods are publicly accessible, that is, public. But how can we make a method in OC inaccessible to the outside world?

This is how it is done in OC. If you want a method not to be accessed by the outside world, you only need to implement this method in the .m file and do not define it in the header file. To put it bluntly: the method has implementation but no definition. In this way, when the outside world imports the header file, there is no such method, but we can use this method in our own .m file.

Why do we need to introduce this knowledge? Because we will talk about the simple interest model later, and this knowledge point will be used then.

#p#

2. Inheritance

Inheritance is an important feature of a class. It makes it unnecessary to write duplicate code and makes it highly reusable. Of course, inheritance in OC is the same as in Java, with little difference. Here is an example:

First, let’s look at the parent class: Car

Car.h

//
// Car.h
// 06_ExtendDemo
//
  // Created by jiangwei on 14-10-11.
  // Copyright (c) 2014 jiangwei. All rights reserved.
//

#import

     @interface Car : NSObject{
NSString *_brand;
NSString *_color;
}

    - (void)setBrand:(NSString *)brand;
  - (void)setColor:(NSString *)color;
- (void)brake;
- (void)quicken;

@end

Two properties and some methods are defined in the Car class

Car.m

//
// Car.m
// 06_ExtendDemo
//
  // Created by jiangwei on 14-10-11.
  // Copyright (c) 2014 jiangwei. All rights reserved.
//

#import "Car.h"

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

Method Implementation

Let’s look at the following classes:

Taxi.h

//
// Taxi.h
// 06_ExtendDemo
//
  // Created by jiangwei on 14-10-11.
  // Copyright (c) 2014 jiangwei. All rights reserved.
//

#import "Car.h"

@interface Taxi : Car{
NSString *_company; //Company
}

//Print invoice
- (void)printTick;

@end

We can see that the Taxi class inherits the parent class Car. Here we need to import the parent class header file, and then add an attribute and method to the Taxi class.

Taxi.m

//
// Taxi.m
// 06_ExtendDemo
//
  // Created by jiangwei on 14-10-11.
  // Copyright (c) 2014 jiangwei. All rights reserved.
//

#import "Taxi.h"

@implementation Taxi

- (void)printTick{
[super brake];
[self brake];
NSLog(@"%@Taxi printed the invoice, company:%@, color:%@",_brand,_company,_color);
}

@end

For the implementation of the method, we can 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 header file of Car is already included in the Taxi.h header file. Moreover, we can use the super keyword to call the parent class method, and we can also use the self keyword to call it. We can see that the effects of these two methods are the same. When we re-implement the brake method in the subclass (the concept of overriding in Java), the super keyword still calls the parent class method, and self calls the overridden brake method. Similarly, we can also use the properties in the parent class.

Let's look at another subclass:

Truck.h

//
//Truck.h
// 06_ExtendDemo
//
  // Created by jiangwei on 14-10-11.
  // Copyright (c) 2014 jiangwei. All rights reserved.
//

#import "Car.h"
//The truck class inherits Car
@interface Truck : Car{
float _maxWeight; //Maximum cargo capacity
}

//Override the parent class's brake method
//Prefer calling subclass methods
- (void)brake;

- (void)unload;

@end

Here we define a brake method ourselves, which will override the brake method in the parent class.

Truck.m

//
//Truck.m
// 06_ExtendDemo
//
  // Created by jiangwei on 14-10-11.
  // Copyright (c) 2014 jiangwei. All rights reserved.
//

#import "Truck.h"

@implementation Truck

- (void)brake{
[super brake];
NSLog(@"brake method in Truck class");
}

- (void)unload{
[super brake]; //Call the parent class method
[self brake];// is also possible
NSLog(@"%@'s truck has unloaded, cargo volume:%.2f, car color:%@",_brand,_maxWeight,_color);
}

@end

Here you can see that we will call the brake method of the parent class in the brake method, and then implement our own logic code.

#p#

Well, that's all about inheritance. In fact, encapsulation and inheritance are not difficult to understand. Let's take a look at the last feature: polymorphism.

3. Polymorphism

Polymorphism is very important for object-oriented thinking. It also plays an important role in the elegant way of writing code in the future. In fact, most of the current design patterns use the characteristics of polymorphism. The polymorphism in Java is very convenient to use, but it is difficult to use in C++. In fact, polymorphism is simply: defining types and actual types, which are generally implemented in the form of interfaces. I won’t say much, just look at the examples:

Printer Example

Abstract printer class Printer

Printer.h

//
// Printer.h
// 07_DynamicDemo
//
  // Created by jiangwei on 14-10-11.
  // Copyright (c) 2014 jiangwei. All rights reserved.
//

#import

     @interface Printer : NSObject

- (void) print;

@end

It is a simple method print

Printer.m

//
// Printer.m
// 07_DynamicDemo
//
  // Created by jiangwei on 14-10-11.
  // Copyright (c) 2014 jiangwei. All rights reserved.
//

#import "Printer.h"

@implementation Printer

- (void)print{
NSLog(@"Printer prints paper");
}

@end

The implementation is also very simple

Let's take a look at the specific subclasses below.

ColorPrinter.h

//
// ColorPrinter.h
// 07_DynamicDemo
//
  // Created by jiangwei on 14-10-11.
  // Copyright (c) 2014 jiangwei. All rights reserved.
//

#import "Printer.h"

//Modify the printing behavior of the parent class
  @interface ColorPrinter : Printer
- (void)print;
@end

ColorPrinter.m

//
// ColorPrinter.m
// 07_DynamicDemo
//
  // Created by jiangwei on 14-10-11.
  // Copyright (c) 2014 jiangwei. All rights reserved.
//

#import "ColorPrinter.h"

    @implementationColorPrinter

- (void)print{
NSLog(@"color printer");
}

@end

Let’s look at another subclass

BlackPrinter.h

BlackPrinter.m
//
// BlackPrinter.m
// 07_DynamicDemo
//
  // Created by jiangwei on 14-10-11.
  // Copyright (c) 2014 jiangwei. All rights reserved.
//

#import "BlackPrinter.h"

    @implementation BlackPrinter

- (void)print{
NSLog(@"black and white printer");
}

@end

Here we define a Person class to operate a specific printer.

Person.h

Person.m
//
// Person.m
// 07_DynamicDemo
//
  // Created by jiangwei on 14-10-11.
  // Copyright (c) 2014 jiangwei. All rights reserved.
//

#import "Person.h"

@implementation Person

/*
 - (void) printWithColor:(ColorPrinter *)colorPrint{
[colorPrint print];
}

  - (void) printWithBlack:(BlackPrinter *)blackPrint{
[blackPrint print];
}
*/

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

@end

Let's look at the test code again:

main.m

//
// main.m
// 07_DynamicDemo
//
  // Created by jiangwei on 14-10-11.
  // Copyright (c) 2014 jiangwei. All rights reserved.
//

#import

#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];

//Definition of polymorphism
/*
         Printer *p1 = [[ColorPrinter alloc] init];
         Printer *p2 = [[BlackPrinter alloc] init];

                  [person doPrint:p1];
[person doPrint:p2];
*/

//Control which printer to use through the command entered by the console
int cmd;
do{
              scanf("%d",&cmd);
if(cmd == 1){
                  [person doPrint:colorPrint];
              }else if(cmd == 2){
                  [person doPrint:blackPrint];
}
}while (1);

}
return 0;
}

Let's explain the benefits of polymorphism in detail.

The above example is a color printer and a black and white printer. There is a method for printing in the Person class. Of course, this method requires a printer object. If the polymorphism mechanism is not used (the commented code part in Person.h), a separate operation method is defined for the two printers, and then the specific printer object is used for operation in Person.m (the commented part in the code). In the main.m file, we can see that when Person needs to use a printer, it calls the specified method:

[person printWithBlack:blackPrint]; //Call black and white printer
[person printWithColor:colorPrint]; //Call the color printer

This design is not good, why? If there is another printer now, then we still need to define a method to operate this printer in Person.h, then what if we add a new printer later? Still adding methods? Then the Person.h file will become very bloated. So at this time, polymorphism will be beneficial. Use the parent class type and define a method in Person.h:

- (void) doPrint:(Printer *)printer;

As you can see here, the parameter type of this method is the type of the parent class. This is polymorphism. The defined type is the parent class type, and the actual type is the subclass type.

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

The print method called here is the print method of the actual type passed in.

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

            [person doPrint:p1];
[person doPrint:p2];

Here, the apparent type of p1 and p2 is Printer, but the actual type is a subclass type, so their corresponding print methods will be called.

From the above examples, we can see that the feature of polymorphism is very important. Of course, it is also the most difficult to understand among the three major features. However, in the process of coding, you will naturally understand it after using it more. There is no need to deliberately understand it.

<<:  How to quickly get started with Xcode 6 in iOS development

>>:  Zhang Xiaolong announces eight rules for WeChat public platform

Recommend

Analysis: What’s so clever about Qutoutiao’s fission strategy?

In 2017, a dark horse, Qutoutiao, emerged in the ...

YaYaYa! The 280th Danxia flyer turned out to be this one!

Danxia bird season is here, and the Guangdong Dan...

SAIF & Industrial Securities: 2024 China Carbon Market System Research Report

Carbon emission quotas are one of the basic tradi...

How to use Zhihu promotion to efficiently attract targeted users?

“Zhihu, share your newly made story with the worl...

User Activation: Breaking Down Luckin Coffee’s New User Activation Process

There are many ways to attract new customers to y...

Better display? The difference between HDR and UHD technology revealed

Friends who are interested in display technology k...

“Curious” marketing: How to create virality?

Curiosity is one of the internal motivations for ...