What is polymorphism

What is polymorphism :

Polymorphism is a variety of forms of a certain kind of thing

cat : cat --> animal

Dog : Dog --> animal

Man : Man --> people --> animal

A woman : A woman --> people --> animal

Polymorphism means that different objects can perform the same action , But through their own implementation code to execute

Polymorphism in the program : Parent pointer to child object

The condition of polymorphism

There is an inheritance relationship

Subclass override parent method

Parent pointer to child object
         
Dog *g = [ Dog new];
         
animal *a = [ Dog
new];
          cat *c = [ cat new];
          animal *a = [ cat new];

performance : When the parent pointer points to a different object , When calling an overridden method through a parent class pointer , Will execute the method of the object that the pointer points to

Advantages of polymorphism

The main advantage of polymorphism is that it simplifies the programming interface . It allows you to reuse some idiomatic naming between classes , Instead of giving each new method a new name . such , A programming interface is a collection of abstract behaviors , So as to distinguish it from the class that implements the interface .

Polymorphism also allows code to be scattered among different objects without trying to consider all possible objects in one method .
This makes your code more extensible and reusable . When a new situation appears , You don't have to modify the existing code changes , Just add a new class and a new method with the same name .

The principle of polymorphism

Dynamic binding :

Dynamic type enables a program to determine the real type of an object until it is executed

Dynamic type binding enables a program to determine which method to call on that object until it is executed

OC New data types and new program modules can be added at runtime : Dynamic type recognition , Dynamic binding , Dynamic loading

id type : Common object pointer types , Weak type , No specific type checking at compile time

Add :

Dynamic data type :    
At compile time, the compiler doesn't know the real type of the variable ,
The real type of it is known only at run time   And if you define variables through dynamic data types , If you access properties and methods that are not dynamic data types , The compiler will not report errors

Static data types :    
By default, all data types are static , You know the type of the variable at compile time , Know which properties and methods are in the variable , These properties and methods can be accessed at compile time , And if you define variables through static data types , If you can't access properties and methods that belong to static data types , Then the compiler will report an error

Richter's principle of substitution :    Subclass objects can be used instead of their parent objects . That is to say “ A child is a parent ”, such as , Man is an animal. , But animals don't have to be people , There is one Animal Class and a class that inherits from Animal Class Person class , 
At this time , Animal A variable of type can point to Person Class , however Person Class type variables cannot point to Animal Class !

Open and closed principle : Software entity ( class   modular   Function, etc. ) It should be possible to extend , But it's not modifiable .  This principle has two characteristics :

One is to say " It's open to expansion (Open for extension) " : It means when there is a new need , The existing software entities can be extended , To meet new needs

One is to say " Closed for changes (Closed for
modification)"  : It means that once the software entity is designed , You can do your job on your own , And don't make any changes to it .

The realization of polymorphism

Examples of people feeding pets :

people (Person)  
Behavior : Feed your pet (feedPet)

Pets (Pets)   Behavior : Eat something (eat)

cat (Cat)        
Behavior : Eat something (eat)

Dog (Dog)       
Behavior : Eat something (eat)

( Cats and dogs Inherited from the pet class )

Sample code :

Pet class declaration implementation :

 #import <Foundation/Foundation.h>
@interface Pets : NSObject
// Eat something
- (void) eat;
@end #import "Pets.h"
@implementation Pets
// Eat something
- (void)eat{
NSLog(@" Pets eat ");
}
@end

Declaration implementation of cat class :

 #import "Pets.h"
@interface Cat : Pets
// Cat specific methods Catch mice
- (void) catchMouse;
@end #import "Cat.h"
@implementation Cat
// Override the parent eat method
- (void)eat{
NSLog(@" People feed pet cats ");
}
// Implement cat specific methods Catch mice
- (void)catchMouse{
NSLog(@" The old cat catches the mouse ");
}
@end

Dog declaration implementation :

 #import "Pets.h"
@interface Dog : Pets
@end #import "Dog.h"
@implementation Dog
// Override the parent eat method
- (void)eat{
NSLog(@" People feed their dogs ");
}
@end

The declaration of humanity has come true :

 #import "Pets.h"
@interface Person : NSObject
// Feed your pet
+ (void) feedPet:(Pets *) pet;
@end #import "Person.h"
@implementation Person
// Feed your pet
+ (void)feedPet:(Pets *)pet{
[pet eat];
}
@end

Main.m :

 #import <Foundation/Foundation.h>
#import "Person.h"
#import "Pets.h"
#import "Dog.h"
#import "Cat.h" int main(int argc, const char * argv[]) {
// The manifestation of polymorphism
Pets * pet = [Pets new];
[Person feedPet:pet]; pet = [Dog new];
[Person feedPet:pet];

pet = [Cat new];
[Person feedPet:pet]; return ;
}

Output results :

 /*
2015-08-31 18:10:06.659 Examples of polymorphism [833:53348] Pets eat
2015-08-31 18:10:06.660 Examples of polymorphism [833:53348] People feed their dogs
2015-08-31 18:10:06.660 Examples of polymorphism [833:53348] People feed pet cats
*/

》 In the code above, we will Dog and Cat Is assigned to Pets Variable of type pet  , That is, the pointer of the parent class type points to the object of the child class , This is Richter's principle of substitution The embodiment of

》 We give Person Class defines a class method :   + (void) feedPet:(Pets) pet;  This method is to receive a Pets Object of type as parameter , Then the method body calls the eating method through the passed in object (eat), We give feedPet The parameters passed by the method are Pets Variable of type pet,  But the output shows that , It's actually called pets separately    Dog and cat   The way to eat   in other words : When the parent pointer points to a different object , Call the overridden method through the parent class pointer , Will execute the method of the object that the pointer points to , This is it. polymorphic

Pay attention to

 
Parent pointer to child object , If you need to call subclass specific methods , You must cast the type to a subclass before calling

 Pets * pet = [Cat new];
// error message : No visible @interface for 'Pets' declares the selector 'catchMouse'
[pet catchMouse];
// Call method after type conversion
[(Cat *)pet catchMouse];

Encapsulating inheritance polymorphism exercises ( The example comes from Big talk design patterns   Written by Cheng Jie )

Implement a computer console program   Two numbers and operators are required   Output results

1.0 edition :

#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
double a =, b = , c = ;
char d = '+';
if(d == '+'){
c = a + b;
}
if( d == '-'){
c = a - b;
}
if( d == '*'){
c = a * b;
}
if( d == '/'){
c = a / b;
}
NSLog(@" Calculation results :%.2lf", c);
return ;
}

Conclusion :

" Good code is good " Get the results you want   It's very good

problem :

1: Variable naming is not standard   a b c d  It doesn't make sense   I don't know what the name is for

2: There is no comment   The program can only be understood for the time being

3: Every if We have to judge

  4: If you divide by 0 What will happen?

2.0 edition :

#import <Foundation/Foundation.h>
int main(int argc, const char * argv[]) {
// The two numbers and operators used for calculation should have user input It's written here dead in the program
double num1 = , num2 = , result = ;
char operate = '+';
// Select the operation mode according to the input operator and get the operation result
switch (operate) {
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
if (num2 != ) {
result = num1 / num2;
}
else{
NSLog(@" The divisor cannot be zero 0"); // Is it a divisor or a divisor Forget
}
break;
}
NSLog(@" The result is : %.2lf", result); return ;
}

Conclusion :

Okay   The variable name looks like something   I won't make unnecessary judgments   And get the results you want   That's no problem

Digest :

" When encountering problems, intuitively describe and express the problems to be solved and the specific solving process with the logic that the computer can understand , There's nothing wrong with that , But this kind of thinking makes our program only to meet the current needs , The program is not easy to maintain , It's not easy to expand , It's not easy to reuse , So we can't meet the requirement of high quality code "

problem :

Now the calculator is just the output of the console   If you want to make a desktop program   Or the calculator on the website   Or mobile apps ??  Copy the code ?? How to reuse code

3.0 edition :

Operation Class declaration file :

// Add one Operation Operation class 
#import <Foundation/Foundation.h> @interface Operation : NSObject
// Pass in two numbers and An operator Get the result
+ (double) getResultOfNum1:(double) num1 andNum2: (double) num2 withOperate:(char) operate;
@end

Operation Class implementation file :

#import "Operation.h"
@implementation Operation
// Get the operation result according to the two numbers and operators passed in
+ (double)getResultOfNum1:(double)num1 andNum2:(double)num2 withOperate:(char)operate{
// Used to store results
double result = ;
// Choose the operation mode and get the result
switch (operate) {
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
if (num2 != ) {
result = num1 / num2;
}
else{
NSLog(@" The divisor cannot be zero 0");
}
break;
}
// Returns the result of the operation
return result;
}
@end

Main.m:

#import <Foundation/Foundation.h>
#import "Operation.h" int main(int argc, const char * argv[]) {
// Two numbers involved in the operation res It is used to store the result of operation
double num1 = , num2 = , res = ;
// Operator
char ope = '*';
// Call the operation method of the operation class to get the result
res = [Operation getResultOfNum1:num1 andNum2:num2 withOperate:ope];
// Printout
NSLog(@" The result is :%.2lf", res); return ;
}

Conclusion :

Now the calculation and display are separated by encapsulation   That is to achieve the separation of business logic and interface logic   Here, the code in the main function is also simplified Don't worry about how to get the result in the method   The code of operation class can be reused without any action

problem :

however How to make the code flexible extension ? For example, we need to add a complement Square root and so on ,  What we need to change now is in the operation class switch Just add a branch to the , But is that really good ? Just adding an operator requires other existing operators to participate in compilation

Examples in the book :

" Now the company wants you to maintain the salary management system , There were only technicians ( a monthly salary ) sales ( Base salary + Royalty ) The manager ( Annual salary + shares ) These three algorithms , Now we need to add a part-time employee ( per diem ) The algorithm of , According to the present practice , The company must give you the class containing the original three algorithms to modify , If we accidentally add the part-time employees' salary algorithm into it at the same time , It's easy to raise the monthly salary of technicians , Isn't it cool , There are always people who are upset "

Optimize :

Separate addition, subtraction, multiplication and division , Modifying one of them doesn't affect the others , Adding arithmetic doesn't affect the existing arithmetic , This is opening up to expansion , Closed to modification -- to open up - Closed principle

4.0 edition :

Operation Class :

#import <Foundation/Foundation.h>
@interface Operation : NSObject
{
@public
double _number1;
double _number2;
}
- (void) setNumber1: (double) number1;
- (void) setNumber2: (double) number2;
// Get the result
- (double) getResult;
@end #import "Operation.h"
@implementation Operation
- (void)setNumber1:(double)number1{
_number1 = number1;
}
- (void)setNumber2:(double)number2{
_number2 = number2;
}
// Get the result
- (double)getResult{
double result = ;
return result;
}
@end

The declarative implementation of the addition class :

#import "Operation.h"
// Addition operation class
@interface OperationAdd : Operation
@end #import "OperationAdd.h"
@implementation OperationAdd
// Get the result of adding two numbers
- (double)getResult{
double result = ;
result = _number1 + _number2;
return result;
}
@end

Declaration implementation of subtraction class :

#import "Operation.h"
// Subtraction operation class
@interface OperationSub : Operation
@end #import "OperationSub.h"
@implementation OperationSub
// Get the result of subtracting two numbers
- (double)getResult{
double result;
result = _number1 - _number2;
return result;
}
@end

The declared implementation of the multiplication class :

#import "Operation.h"
// Multiplication class
@interface OperationMul : Operation
@end #import "OperationMul.h"
@implementation OperationMul
// Get the result of multiplication of two numbers
- (double)getResult{
double result = ;
result = _number1 * _number2;
return result;
}
@end

Declaration implementation of division class :

#import "Operation.h"
// Division operation class
@interface OperationDiv : Operation
@end #import "OperationDiv.h"
@implementation OperationDiv
// Get the result of dividing two numbers
- (double)getResult{
double result = ;
if (_number2 != ) {
result = _number1 / _number2;
}
else{
NSLog(@" The divisor cannot be zero 0");
}
return result;
}
@end

Declaration implementation of factory class :

#import "OperationAdd.h"
#import "OperationSub.h"
#import "OperationMul.h"
#import "OperationDiv.h" // It is specially used to get the instance of operation class
@interface GetOperation : NSObject
+ (Operation *) createOperationWithOperate: (char) operate;
@end #import "GetOperation.h"
@implementation GetOperation
// Get the operation class instance
+ (Operation *)createOperationWithOperate:(char)operate{
// Application of polymorphism The parent class pointer points to the child class instance object
Operation * ope = nil;
// Get the corresponding instance object according to the operator passed in
switch (operate) {
case '+':
ope = [OperationAdd new];
break;
case '-':
ope = [OperationSub new];
break;
case '*':
ope = [OperationMul new];
break;
case '/':
ope = [OperationDiv new];
break;
}
return ope;
}
@end

Main.m:

#import <Foundation/Foundation.h>
#import "GetOperation.h" int main(int argc, const char * argv[]) {
double num1 = , num2 = , res = ;
char operate = '*'; Operation * ope = [GetOperation createOperationWithOperate:operate];
ope.number1 = num1;
ope.number2 = num2; res = [ope getResult];
NSLog(@" The result is : %.2lf", res); return ;
}

Now if you want to modify one of these operations It doesn't affect any other operations   If you want to add a new operation   You just need to add a new operation class   Then modify it in the factory method switch Just a branch   There is no need to provide the original operation class   So it will not affect other existing operation classes   In this way, opening up is realized - Closed principle

Digest : " Programming is a technology , It's more of an art , You can't just be satisfied with writing the code and running it correctly , Always think about how to make your code simpler , Easier to maintain , Easy to expand and reuse , Only in this way can we really improve "

OC Basics -- polymorphic And More articles about the three characteristics exercises

  1. OC Basics Three characteristics of class

    OC Basics   Three characteristics of class OC Class and JAVA equally , They all have three characteristics : Inherit , encapsulation , polymorphic , So let's take a look OC There are three characteristics of the middle class . 1. Inherit The characteristics of inheritance : (1) Subclasses inherit properties and methods from their parents . (2) A genus unique to a subclass ...

  2. OC Basics — polymorphic ( Super easy )

    Preface : oc There are two pointer type variables in : One is compile time type , One is the runtime type , The compile time type is determined by the type used to declare the variable , The runtime type is determined by the object actually assigned to the variable . If the compile time type and run time type are not the same , It's possible to have polymorphism ...

  3. Java Basics - The third feature of object-oriented is polymorphism (polymorphism )

    Java Basics - The third feature of object-oriented is polymorphism (polymorphism) author : Yin Zhengjie Copyright notice : Original works , Declined reprint ! Otherwise, the legal liability will be investigated . One . Overview of polymorphism Polymorphism is followed by encapsulation , After inheritance , The third major feature of object-oriented , Polymorphic ...

  4. 5、 ... and .OC Basics --1. polymorphic ,2. Class object ,3. Some grammar ,4.@property&amp;@synthesize,5. Dynamic type , introspection ( Determine whether the object follows a specific protocol , And whether it can respond to specific messages )

    5、 ... and .OC Basics --1. polymorphic , 1. The concept of polymorphism , Definition : Polymorphism is a variety of forms of a certain kind of thing : form : Animal *ani = [Dog new]; Polymorphic conditions :1. There is an inheritance relationship 2. Rewriting with methods 2. Polymorphic code ...

  5. [.net Fundamentals of object-oriented programming ] (13) Three characteristics of object-oriented —— polymorphic

    [.net  Fundamentals of object-oriented programming ] (13)  Three characteristics of object-oriented —— polymorphic The first two sections , We learned about the encapsulation and inheritance features of object-oriented , Another feature of object orientation is polymorphism . Compared to the previous encapsulation and inheritance , The concept of polymorphism is not so easy to understand . We ...

  6. understand java The three characteristics of polymorphism ( 3、 ... and )

    Excerpt from :http://cmsblogs.com/?p=52 There are three characteristics of object-oriented programming : encapsulation . Inherit . polymorphic . Encapsulation hides the internal implementation mechanism of classes , You can change the internal structure of a class without affecting its use , It also protects data . It's just for the outside world ...

  7. OC Basics 11: Basic C Linguistic characteristics 2

    "OC Basics " This classified article is my self-study Stephen G.Kochan Of <Objective-C Programming part 6 edition > Notes in the process . 19. Define a int Pointer to type : int ...

  8. OC Basics 10: Basic C Linguistic characteristics 1

    "OC Basics " This classified article is my self-study Stephen G.Kochan Of <Objective-C Programming part 6 edition > Notes in the process . 1.  The difference between function and method ? (1). Method pack ...

  9. OC Basics 6: polymorphic 、 Dynamic types and dynamic binding

    "OC Basics " This classified article is my self-study Stephen G.Kochan Of <Objective-C Programming part 6 edition > Notes in the process . 1. About SEL Data of type : (1).SEL ...

Random recommendation

  1. quick-cocos2d-x : Join the learning

    Not familiar with grammar , I'm not familiar with the interface . Part of it doesn't understand . Super beginner . study hard , Always learning Use Quick-Cocos2d-x Build a horizontal version of the game Recommend official documents and examples  demo

  2. How to publish and deploy asp.net Website

    use vs To develop the asp.net How to publish the website to the server to become an official website ? 1. To publish, we need to publish the website first , This step is to generate the directory of the official website ( Compile the source code into .cs The code file is compiled into .dll file ) The detailed steps :http:// ...

  3. Two-Phase Commit ( Two-phase commit )

    1. technological process 1) Coordinator ( The coordinator ) radio broadcast VOTE-REQ To all Participant ( participants ) 2) Coordinator wait for Participant Result 3) Pa ...

  4. JavaScript substring() Method

    Definition and Usage substring() Method is used to extract characters that are mediated between two specified subscripts . grammar stringObject.substring(start,stop) Parameters describe start It's necessary . A non negative ...

  5. Cygwin Package manager :apt-cyg

    Reference resources <Cygwin Package manager :apt-cyg> cygwin The next installation needs to be started every time set_up, Compared with egg pain , still debian Of apt convenient , You should see it on the Internet cygwin Under the apt, I think it's good . from h ...

  6. A summary of the ways of network connection (HostOnly,NAT....)

    The real network structure : The line on the left side of the leftmost computer represents , If this computer has a network card, it can connect to other computers . At one Windows of use VMware To install a Linux System ( Dotted lines are not real ) Where is the virtual gateway in the picture above ...

  7. Codevs 1171 Lurker 2009 year NOIP National League improvement section

    1171 Lurker 2009 year NOIP National League improvement section The time limit : 1 s Space restriction : 128000 KB Question level : gold Gold Title Description Description [ Problem description ] R Guohe S The country is sinking into ...

  8. spring-security The configuration file

    from :spring-security Learning notes -- The configuration file <?xml version="1.0" encoding="UTF-8"?> <be ...

  9. C# Design mode 2 factory method mode (Factory Method Pattern)【 Creation type 】

    One . introduction In the last article, we explained a pattern of transition called [ Simple factory ], It's also called [ Static factory ] Of , By understanding the simple factory model , We also found its shortcomings , With the change of requirements, we constantly modify the code of the method in the factory , change in demand ...

  10. Vue State management (vuex) Interface call

    Vue State management (vuex) Interface call One , Introduction and requirements 1.1, Introduce 1, State management (vuex) Vuex Is a special for Vue.js State management mode of application development . It USES centralized storage to manage the state of all components of the application ...