Subclass behavior cannot exceed the parent behavior-let's talk about the basic principle of object orientation, and let's replace it.

Source: Internet
Author: User
Subclass behavior cannot exceed parent Behavior
-- Talking about the basic principles of object orientation from the perspective of Pattern Principle: The child type must be able to replace its base type.
This is the famous Liskov replacement principle (LSP ),Also known Rys replacement principle.
The general understanding of this principle is that the methods of the parent class must be implemented or overwritten in the subclass, and the methods not defined by the parent class are not allowed in the subclass.
As we mentioned earlier, the dependency inversion principle is that parent classes cannot depend on child classes, and they all depend on abstract classes. We say this dependency is the basis for code extension and runtime binding (polymorphism. Once a class user is dependent on a specific class, the extension of the dependency is impossible. If a class is dependent on an abstract class, only the subclass of the abstract class is implemented, can be used by class users to achieve system expansion.
However, relying on the reverse principle does not necessarily enable good scalability and runtime binding for our code. See the following code:
Public class animal
{
Private string name;
Public animal (string name)
{
This. Name = Name;
}
Public void descriptiion ()
{
System. Out. println ("This is a (an)" + name );
}
}
Below is its subclass:
Public class cat extends animal
{
Public CAT (string name)
{
Super (name );
}
Public void MEW ()
{
System. Out. println ("the cat is saying like 'mew '");
}
}
Then let's take a look at the implementation of dog:
Public class dog extends animal
{
Public dog (string name)
{
Super (name );
}
Public void bark ()
{
System. Out. println ("the dog is saying like 'bark '");
}
}
Finally, let's look at the client call:
Public decriptiontheanimal (animal)
{
If (animal instanceof cat)
{
Cat cat = (CAT) animal;
Cat. decription ();
Cat. MEW ();
}
Else if (animal instanceof dog)
{
Dog dog = (DOG) animal;
Dog. decription ();
Dog. Bark ();
}
}
Through the code above, we can see that although the client dependency is abstract, the design's scalability is still poor, and the binding is not implemented at runtime.
Why? In fact, this is because it does not meet the requirements of the Rys replacement principle. For example, CAT has no MEW () method parent class, and the dog class has no bark () method parent class, neither subclass can replace the parent class. This leads to poor system scalability and failure to bind during runtime.
Now it seems that a system or subsystem must have good scalability and be bound during runtime. There are two necessary conditions: first, the dependency inversion principle; and second, the lining replacement principle. These two principles are indispensable.
Benefit of the Rys replacement principle:
First, ensure that the system or subsystem has good scalability. Only when the child class can completely replace the parent class can the system or sub-system recognize the child class during the runtime, so that the system or sub-system has good scalability.
Second, binding during runtime ensures the smooth development of object-oriented polymorphism. This saves a lot of code duplication or redundancy. Avoid statements like instanceof or getclass (). These statements are taboo for Object-Oriented purposes.
Third, it is conducive to implementing contractual programming. Contractual programming is conducive to system analysis and design. It refers to defining system interfaces during analysis and design and implementing these interfaces when coding. Define the functions that sub-classes need to implement in the parent class, and sub-classes only need to implement these functions.
We know that in most of our modes, we all have a common interface, and then both the subclass and the extension class implement this interface. Here, we use the command mode as an example.
The following is a piece of original code:
If (action. Equals ("add "))
{
// Do add action
......
}
Else if (action. Equals ("view "))
{
// Do view action
......
}
Else if (action. Equals ("delete "))
{
// Do Delete action
......
}
Else if (action. Equals ("modify "))
{
// Do modify action
......
}
The first thing we think of is to separate these actions and write the following code:
Public class addaction
{
Public void add ()
{
// Do add action
......
}
}
Public class viewaction
{
Public void view ()
{
// Do view action
......
}
}
Public class deleteaction
{
Public void Delete ()
{
// Do Delete action
......
}
}
Public class modifyaction
{
Public void modify ()
{
// Do modify action
......
}
}
As we can see, this code separates individual behaviors and satisfies the single responsibility principle, but this is far from enough because it does not meet the Dependency inversion principle and the Lee's replacement principle.
Let's take a look at the solution to this problem in the command mode:
First, define an interface:
Public interface action
{
Public void doaction ();
}
Then there are various implementations:
Public class addaction implements action
{
Public void doaction ()
{
// Do add action
......
}
}
Public class viewaction implements action
{
Public void doaction ()
{
// Do view action
......
}
}
Public class deleteaction implements action
{
Public void doaction ()
{
// Do Delete action
......
}
}
Public class modifyaction implements action
{
Public void doaction ()
{
// Do modify action
......
}
}
In this way, the client call is roughly as follows:
Public void execute (action Action)
{
Action. doaction ();
}
Check that the above client code has no such statement as instanceof, and has good scalability and advantages of binding during runtime.
Here, we only use the command mode as an example to see how the mode complies with the Lee's replacement principle. Examples of other models are no longer provided. We can see that almost all models follow this principle. If you don't believe it, you can find it on your own.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.