Current location - Training Enrollment Network - Books and materials - What is an abstract class?
What is an abstract class?
Understanding abstract classes

Abstract classes and interfaces are used to define abstract classes in Java language (abstract classes in this paper are not translated from abstract classes, but represent an abstract body, and abstract classes are methods used to define abstract classes in Java language, please pay attention to the distinction). So what is abstract class and what benefits can it bring us?

In the concept of object-oriented, we know that all objects are described by classes, but the reverse is not the case. Not all classes are used to describe objects. If a class does not contain enough information to describe a specific object, such a class is an abstract class. Abstract classes are usually used to represent abstract concepts that we get in the analysis and design of problem areas. They are abstractions of a series of concrete concepts, which look different but are essentially the same. For example, if we develop a graphic editing software, we will find that there are some specific concepts such as circles and triangles in the problem domain. They are different, but they all belong to the concept of form. The concept of shape does not exist in the problem domain, but it is an abstract concept. It is precisely because abstract concepts have no corresponding concrete concepts in the problem domain that abstract classes used to represent abstract concepts cannot be instantiated.

In the object-oriented field, abstract classes are mainly used for type hiding. We can construct an abstract description of a set of fixed behaviors, but this set of behaviors can have any possible concrete implementation. This abstract description is an abstract class, and any possible concrete implementation of this group is represented by all possible derived classes. Modules can manipulate abstractions. Because the module depends on a fixed abstraction, it may not be allowed to be modified; At the same time, by deriving from this abstract body, the behavioral function of this module can also be extended. Readers who are familiar with OCP must know that abstract classes are the key to realize the core principle of object-oriented design, OCP (open closed principle).

On abstract classes and interfaces from the perspective of grammar definition

At the grammatical level, Java language gives different definitions of abstract classes and interfaces. Let's take the definition of an abstract class named Demo as an example to illustrate this difference.

The method of demonstrating abstract classes by using abstract class definition is as follows:

Abstract class demonstration {

Abstract void method1();

Abstract void method 2 ();

}

Using interface definitions to demonstrate abstract classes is as follows:

Interface demonstration {

Void method1();

Void method 2 ();

}

In abstract class mode, Demo can have its own data members or non-abstract member methods, while in the implementation of interface mode, Demo can only have unmodifiable static data members (that is, it must be static final, but generally no data members are defined in the interface), and all member methods are abstract. In a sense, interface is a special form of abstract class.

From the programming point of view, both abstract classes and interfaces can be used to realize the idea of "design by contract". But there are still some differences in specific use.

First of all, abstract classes represent an inheritance relationship in Java language, and a class can only use the inheritance relationship once. However, a class can implement multiple interfaces. Perhaps this is a compromise when the designers of Java language consider Java's support for multiple inheritance.

Secondly, in the definition of abstract classes, we can give methods the default behavior. However, in the definition of an interface, a method cannot have a default behavior. In order to get around this restriction, we must use delegation, but this will increase some complexity and sometimes cause great trouble.

Another serious problem is that the default behavior cannot be defined in abstract classes, which may cause maintenance trouble. Because if you want to modify the interface of a class in the future (usually represented by abstract classes or interfaces) to adapt to new situations (such as adding new methods or adding new parameters to used methods), it will be very troublesome and may take a lot of time (especially in the case of many derived classes). However, if the interface is implemented through an abstract class, you may only need to modify the default behavior defined in the abstract class.

Similarly, if the default behavior cannot be defined in the abstract class, the same method implementation will appear in every derived class of the abstract class, which violates the principle of "one rule, one place", causes code duplication and is not conducive to future maintenance. Therefore, be very careful when choosing between abstract classes and interfaces.

On abstract classes and interfaces from the perspective of design concepts

The difference between abstract classes and interfaces is mainly discussed from the perspective of syntax definition and programming. The differences between these levels are relatively low-level and non-essential. This section will analyze the difference between abstract classes and interfaces from another aspect: the design concept they reflect. The author believes that only by analyzing from this level can we understand the essence of these two concepts.

As mentioned earlier, the abstarct class embodies the inheritance relationship in the Java language. In order to make the inheritance relationship reasonable, there must be a "Shi A" relationship between the parent class and the derived class, that is, the parent class and the derived class should be the same in concept (reference [3] has a lot of in-depth discussion on the "Shi A" relationship, which can be referred by interested readers). This is not the case for interfaces. It is not required that the implementer of the interface and the definition of the interface are conceptually consistent, and only the contract of the interface definition is realized. In order to make the discussion easy to understand, the following will be illustrated by a simple example.

Consider such an example. Suppose there is an abstract concept about the door in our problem domain, and the door has two actions, opening and closing. At this time, we can define a type representing an abstract concept through an abstract class or interface. The definition method is as follows:

Define doors using abstract classes:

Abstract class door (

Abstract void open ();

Abstract void close ();

}

Use the interface to define the door:

Interface door (

void open();

void close();

}

Other concrete door types can be defined through abstract classes in extensions or interfaces in implementations. There seems to be not much difference between using abstract classes and interfaces.

If a door is needed now, it should also have an alarm function. How can we design the class structure for this example (in this example, it is mainly to reflect the difference between abstract classes and interfaces in design concept, and other irrelevant issues are simplified or ignored)? The possible solutions will be listed below, and these different solutions will be analyzed from the design concept level.

Solution 1:

Just add an alarm method to the definition of the door, as shown below:

Abstract class door (

Abstract void open ();

Abstract void close ();

Abstract void alarm ();

}

or

Interface door (

void open();

void close();

void alarm();

}

Then the alarm door with alarm function is defined as follows:

Class AlarmDoor extension door {

void open() { … }

void close() { … }

Invalid alarm () {...}

}

or

AlarmDoor class tool door {

void open() { … }

void close() { … }

Invalid alarm () {...}

}

This method violates one of the core principles of object-oriented design, ISP (Interface Isolation Pripler). In the definition of door, the inherent behavior of the concept of door is mixed with the behavior of another concept "alarm". One of the problems caused by this is that those modules that only rely on the concept of door will change because of the change of the concept of "alarm" (such as modifying the parameters of alarm method), and vice versa.

Solution 2:

Since open, close and alarm belong to two different concepts, they should be defined in an abstract class representing these two concepts according to ISP principles. Definitions are as follows: These two concepts are defined by abstract classes; Both of these concepts are defined by interfaces; One concept is defined by abstract classes, and the other concept is defined by interfaces.

Obviously, because the Java language does not support multiple inheritance, it is not feasible to define these two concepts by abstract classes. The latter two methods are feasible, but their choice reflects the understanding of the concept essence in the problem domain and whether the reflection of the design intention is correct and reasonable. Let's analyze and explain.

If both concepts are defined by interfaces, then two problems are reflected: 1. We may not understand the problem domain clearly. Is AlarmDoor essentially a door or an alarm? 2. If we have no problem with the understanding of the problem domain, for example, through the analysis of the problem domain, we find that the concept of AlarmDoor and the concept of Door are essentially the same, then we can't correctly reveal our design intention when implementing it, because the above meanings can't be reflected in the definitions of these two concepts (both are defined through interfaces).

If our understanding of the problem area is: AlarmDoor is essentially a door, which has the function of alarm. How can we design and implement it to clearly reflect our meaning? As mentioned earlier, abstract classes represent an inheritance relationship in Java language, which is essentially a "yes" relationship. Therefore, for the concept of door, we should define it with the method of abstract class. In addition, the AlarmDoor has an alarm function, which means that it can complete the behavior defined in the alarm concept, so the alarm concept can be defined through the interface. As follows:

Abstract class door (

Abstract void open ();

Abstract void close ();

}

Interface alarm {

void alarm();

}

Alarm Level Door Extension Door Tool Alarm {

void open() { … }

void close() { … }

Invalid alarm () {...}

}

This realization method can basically clearly reflect our understanding of the problem domain and correctly reveal our design intention. In fact, the abstract class represents the "is a" relationship, and the interface represents the "like an" relationship, which can be used as the basis for everyone to choose. Of course, this is based on the understanding of the problem domain. For example, we think that the AlarmDoor is essentially an alarm and has the function of a door, then the above definition is reversed.