Object oriented and process oriented

Process oriented

The problem is decomposed into a step by step implementation, can be called in turn.

Example: Calculate the area of a rectangle

public double  calculateArea(double long,double wide){

    double area  =   long * wide;
    return area;
}
        
Copy the code

object-oriented

The problem is decomposed into a step by step, and each step is abstracted accordingly to form objects. The problem is solved by combination of calls between different objects.

/** * Rectangle{/** * Rectangle{/** * Rectangle{/** * Rectangle */ private double long; /** * private double wide; public Rectangle(double long,double wide){ this.long =long; this.wide = wide; } /** * calculateArea */ public double calculateArea(){return this.long * this.wide; }} public Test{public static void main(String[] arges){Rectangle = new Rectangle(1,2); rectangle.calculateArea(); }}Copy the code

The basic features and principles of object orientation

Three characteristics of object orientation

encapsulation

The so-called encapsulation is to encapsulate objective things into abstract classes, and classes can only allow their own data and methods to be operated by trusted classes or objects, to hide the information of the untrusted.

Simply put, a class is a logical entity that encapsulates data and the code that operates on that data. Inside an object, some code or some data can be private and not accessible to the outside world, so that the data is protected inside the abstract data type. Objects provide different levels of protection for internal data. In order to prevent the unexpected change of the irrelevant part of the program or the wrong use of the private part of the object, as far as possible to hide the details, only retain some external interface to make it and external contact, users do not need to know the internal details of the object, but can access the object through the interface provided by the object.

Advantages:

  • Reduced coupling: Can be developed, tested, optimized, used, understood, and modified independently
  • Reduced maintenance burden: easier to understand by programmers and can be debugged without affecting other modules
  • Tune performance effectively: Profiling can be used to determine which modules affect system performance
  • Improve software reusability
  • Reduces the risk of building large systems: these individual modules may be available even if the entire system is not

inheritance

Inheritance refers to the ability to implement IS-A relationships to obtain non-private properties and methods. It can take all the functionality of an existing class and extend it without having to rewrite the original class. A class (called a subclass, subinterface) inherits the functionality of another class (called a parent class, parent interface) and can add its own new functionality. So the root cause of inheritance is reuse, and the root cause of implementation is the need to define a standard.

In Java, inheritance is implemented using the extends keyword and implementation is implemented through the implements keyword

Inheritance should follow the Richter’s substitution principle. Subclass objects must be able to replace all superclass objects.

New classes created by inheritance are called “subclasses” or “derived classes,” and inherited classes are called “base classes,” “parent classes,” or “superclasses.” The process of inheritance is the process of going from general to particular.

polymorphism

The concept of polymorphism is relatively simple, that is, the same operation on different objects can be interpreted differently, resulting in different execution results.

  • Compile-time polymorphism mainly refers to method overloading
  • Runtime polymorphism refers to the type to which an object reference defined in a program points only at run time

A necessary condition for polymorphism

In order to implement runtime polymorphism, or dynamic binding, three conditions need to be met:

  • inheritance
  • Overwrite (override)
  • upcasting

There is class inheritance or interface implementation

Subclasses override methods of their parent class

A reference to a parent class points to an object of a subclass

Five basic principles of object orientation

The single-responsibility Principle

The core idea is that it is best for a class to do only one thing, and only one thing to cause it to change. The principle of single responsibility can be regarded as an extension of the object-oriented principle of low coupling and high cohesion. Responsibility is defined as the cause of change, so as to improve cohesion to reduce the cause of change. If there are too many responsibilities, there will be more reasons to cause it to change, which will lead to responsibility dependence and influence each other, thus greatly damaging its cohesion and coupling degree. Single responsibility, in the usual sense, means that there is only one single function. Do not implement too many function points for a class to ensure that the entity has only one cause for its change. Concentration, is a person’s excellent quality; Similarly, singleness is a good design for a class. Mixed up responsibilities can make code look awkward, unappealing, and inevitably lead to ugly system errors.

The Open-Closed principle

The core idea is that software entities should be extensible, not modifiable. That is, open to extension, closed to modification. The principle of openness and closure is mainly reflected in two aspects: 1. Openness to extension, which means that existing code can be extended to adapt to new requirements or changes. 2. Being closed to changes means that once a class is designed, it can do its work on its own without making any attempted changes to it. The core idea of implementing the open closed principle is to program for abstractions, not concrete ones, because abstractions are relatively stable. Make classes dependent on fixed abstractions, so modifications are closed; And through the object-oriented inheritance and polymorphic mechanism, and can realize the inheritance of abstract class, by overwriting its method to change the inherent behavior, to achieve new expansion methods, so it is open. “Demand is always changing” there is no constant software, so it is necessary to use the closed and open principle to seal the change to meet the demand, but also to maintain the stability of the packaging system inside the software, not to be affected by the change of demand.

Liskov-substitution Principle

The idea is that subclasses must be able to replace their base classes. This idea is reflected in the constraint specification of inheritance mechanism. Only when the subclass can replace the base class, can the system recognize the subclass in the running period, which is the basis for ensuring inheritance reuse. In the specific behavior of the parent class and the subclass, the relationship and characteristics in the inheritance hierarchy must be strictly grasped, and the behavior of the program will not change if the base class is replaced by the subclass. At the same time, this constraint is reversed is not true, the subclass can replace the base class, but the base class does not necessarily replace the subclass. Liskov substitution principle focuses on inheritance based on abstraction and polymorphism. Therefore, only following The Liskov substitution principle can ensure that inheritance reuse is reliable. The approach is interface-oriented programming: abstracting the common parts into base Class interfaces or Abstract classes, using Extract Abstract Class, and implementing new ways to support the same responsibilities in subclasses by overwriting the parent Class’s methods. Liskov substitution principle is a design principle about inheritance mechanism. Violation of Liskov substitution principle will inevitably lead to violation of open and closed principle. Liskov substitution principle can ensure the system has good extensibility, and realize the abstraction mechanism based on polymorphism, which can reduce code redundancy and avoid type discrimination at runtime.

Dependecy-inversion Principle

The core idea is: rely on abstraction. In particular, high-level modules do not depend on low-level modules, and both depend on abstraction; Abstract does not depend on concrete, concrete depends on abstraction. We know that dependencies must exist between classes and modules. When there is a tight coupling relationship between two modules, the best way is to separate the interface and implementation: define an abstract interface between the dependencies so that the high-level module calls the interface, and the low-level module implements the definition of the interface, so as to effectively control the coupling relationship and achieve the design goal dependent on abstraction. The stability of abstraction determines the stability of the system, because abstraction is immutable, and dependence on abstraction is the essence of object-oriented design and the core of dependency inversion principle. Dependence on abstraction is a general principle, and dependence on detail is inevitable at some point. Trade-offs must be made between abstraction and concreteness. To rely on abstractions is to program interfaces, not implementations.

Interface Segregation Principle

The idea is to use multiple small, specialized interfaces rather than one large, general interface. To be specific, the interface isolation principle is as follows: Interfaces should be cohesive and “fat” interfaces should be avoided. A class’s dependency on another class should be based on the smallest interface. Do not force dependencies on different methods, which is a form of interface pollution. Interfaces provide all the benefits of abstract programming by effectively separating details from abstractions, and interface isolation emphasizes interface singleness. However, fat interfaces have obvious disadvantages, which will lead to the type of implementation must fully implement all the methods and attributes of the interface. Sometimes the implementation type does not require all the interface definitions, which is wasteful in design and potentially problematic in implementation. Changes to a fat interface can lead to a cascade of client programs that need to be modified, sometimes a disaster. In this case, splitting the fat interface into custom methods with multiple characteristics makes clients rely only on the methods they actually call, freeing clients from relying on methods they don’t use. There are two main methods of delegation separation: 1. Delegation separation: a new type is added to delegate the request of the customer, isolating the direct dependence between the customer and the interface, but increasing the overhead of the system. 2, multiple inheritance separation, through the interface multiple inheritance to achieve customer requirements, this way is better.

These are the five basic object-oriented design principles that, like the golden rule of object-oriented programming, make our code more alive, easy to reuse, easy to extend, flexible and elegant. Different design patterns correspond to different needs, while design principles represent the eternal soul and need to be observed in practice all the time. As ARTHUR J. Riel says over there in the Book of OOD: “You do not have to follow these principles strictly, and disobeying them will not result in religious punishment. But you should think of these principles as alarm bells, and if you break one of them, alarm bells will go off.”