Details the differences between abstract classes and interfaces in Java

  • 2020-04-01 03:32:53
  • OfStack

Abstract class and interface are two mechanisms that support abstract class definitions in the Java language. It is these two mechanisms that give Java its powerful object-oriented capabilities. Abstract class and interface are very similar in their support for abstract class definitions, and can even be interchangeable, so many developers choose abstract class and interface at will when entering abstract class definitions. In fact, there is a big difference between the two, and the choice of them even reflects the understanding of the nature of the problem domain and whether the understanding of the design intention is correct and reasonable. This article will examine the differences between them in an attempt to give developers a basis for choosing between them.

Understanding abstract classes

The abstract class and interface in the Java language is used for an abstract class (in this article an abstract class is not from the abstract class translation, it said is an abstract, and the abstract class for the Java language is used to define a method of abstract class, please pay attention to distinguish) defined, so what's an abstract class, using an abstract class can bring us any good?

In object-oriented concepts, we know that all objects are represented by classes, but not the other way around. Not all classes are intended to represent objects, and if a class does not contain enough information to represent a concrete object, such a class is an abstract class. Abstract classes are often used to represent the abstract concepts that we derive from our analysis and design of the problem domain. They are abstractions of a series of concrete concepts that look different but are essentially the same. For example, if we develop a graphics editing software, we will find that there are some concrete concepts such as circle and triangle in the problem domain, they are different, but they all belong to the concept of shape, the concept of shape does not exist in the problem domain, it is an abstract concept. Because abstract concepts have no corresponding concrete concepts in the problem domain, abstract classes representing abstract concepts cannot be instantiated.

In the object-oriented world, abstract classes are mainly used for type hiding. We can construct an abstract description of a fixed set of behaviors, but this set of behaviors can be implemented in any concrete way possible. This abstract description is the abstract class, and this set of any possible concrete implementations is represented as all possible derived classes. A module can operate on an abstract body. Because a module depends on a fixed abstraction, it can be unmodifiable; At the same time, the behavior of this module can be extended by deriving from this abstraction. Readers familiar with OCP will know that abstract classes are the key to one of the most core principles of object-oriented design, the OCP(open-closed) Principle.

Abstract class and interface at the level of syntax definition

At the syntax level, the Java language defines abstract class and interface in different ways. Here's an example of how to define an abstract class named Demo.

Using abstract class to define the Demo abstract class is as follows:


abstract class Demo {
abstract void method1();
abstract void method2();
...
}

Interface is used to define the Demo abstract class as follows:


interface Demo{
void method1();
void method2();
...
}

In the abstract class method, Demo can have its own data members and non-abstract member methods. However, in the interface method, Demo can only have static data members that cannot be modified (that is, they must be static final, but data members are not generally defined in the interface), and all member methods are abstract. In a sense, interface is a special form of abstract class.

From a programming perspective, abstract class and interface can both be used to implement the idea of "design by contract". But there are some differences in the specific use.

First, abstract class represents an inheritance relationship in the Java language that can only be used once by a class (because Java does not support multiple inheritances -- annotations). However, one class can implement multiple interfaces. Perhaps this was a compromise between the designers of the Java language and Java's support for multiple inheritance.

Second, in the definition of abstract class, we can give methods their default behavior. However, in the definition of interface, methods cannot have default behavior, and in order to get around this limitation, delegates must be used, but this can add some complexity and sometimes cause a lot of trouble.

Another serious problem with not being able to define default behavior in an abstract class is that it can cause maintenance problems. This is because if you later want to modify the interface of the class (typically represented by abstract class or interface) to accommodate new situations (for example, adding new methods or adding new parameters to existing methods), it can be very cumbersome and can take a lot of time (especially if there are many derived classes). But if the interface is implemented in abstract class, then you probably just need to modify the default behavior defined in abstract class.

Similarly, failure to define default behavior in an abstract class results in the same method implementation appearing in every derived class of that abstract class, violating the "one rule, one place" principle, causing code duplication, and also detrimental to future maintenance. Therefore, be very careful when choosing between abstract class and interface.

Abstract class and interface from the perspective of design philosophy

The above mainly discusses the difference between abstract class and interface from the perspective of grammar definition and programming. The differences between these levels are relatively low-level and non-essential. This section will examine the differences between abstract class and interface from another level: the design concept reflected in the abstract class and interface. According to the author, the essence of the two concepts can only be understood through this analysis.

As mentioned earlier, abstract class embodies an inheritance relationship in the Java language. To make the inheritance relationship reasonable, there must be an "is-a" relationship between the parent and derived classes, which means that the concepts of the parent and derived classes should be essentially the same. In the case of interface, it doesn't require that the implementer of the interface and the definition of the interface are essentially identical in concept, it just implements the contract of the definition of the interface. To make the argument easy to understand, a simple example will follow.

Consider such an example. Suppose there is an abstract concept about Door in our problem domain, and the Door has two actions of open and close. At this time, we can define a type to represent the abstract concept through abstract class or interface.

Use abstract class to define Door:


abstract class Door{
abstract void open();
abstract void close() ;
}

Use interface to define Door:


interface Door{
void open();
void close();
}

Other concrete Door types can be extends using Door defined in abstract class or implements using Door defined in interface. It looks like there's no big difference between using abstract class and interface.

If the Door is now required to have the function of alarm. How do we design the class structure for this example (in this case, mainly to show the difference between abstract class and interface reflected in the design concept, other aspects of the irrelevant issues are simplified or ignored)? Below is a list of possible solutions and an analysis of these different solutions from the design philosophy level.

Solution 1:

Simply add an alarm method to the definition of Door as follows:


abstract class Door{
abstract void open();
abstract void close() ;
abstract void alarm();
}

or


interface Door{
void open();
void close();
void alarm();
}

So the AlarmDoor is defined as follows:


class AlarmDoor extends Door{
void open(){ ... }
void close(){ ... }
void alarm(){ ... }
}

or


class AlarmDoor implements Door {
void open(){ ... }
void close(){ ... }
void alarm(){ ... }
}

This approach violates one of the core principles of object-oriented design, ISP, by mixing the intrinsic behavior of the concept of Door with the behavior of another concept, the "alarm." One problem with this is that modules that rely solely on the concept of Door will change as the concept of "alarm" changes (for example, by modifying the parameters of the alarm method), and the reverse remains true.

Solution 2:

Since open, close, and alarm belong to two different concepts, they should be defined separately in the abstract class that represents them according to the ISP principle. The two concepts are defined in the abstract class way. Both concepts are defined using interface; One concept is defined in the abstract class way, the other in the interface way.

Clearly, since the Java language does not support multiple inheritance, it is not feasible to define both concepts using abstract class. The latter two approaches are both feasible, but the choice of them reflects the understanding of the conceptual nature of the problem domain and the correctness and rationality of the design intent. We will analyze and explain.

If both concepts are defined using interface, then two problems are highlighted: 1. We may not understand the problem area clearly, AlarmDoor is Door or alarm in essence in the concept? 2, if our understanding of the problem domain, there is no problem, for example: we found through analysis for the problems in the field of AlarmDoor concept in nature and feel is consistent, so when we realize there is no correctly reveal our design intent, because in the definition of these two concepts (using the interface definition) does not reflect the meaning.

If our understanding of the problem area is that AlarmDoor is essentially Door in concept and has alarm functionality. How can we design and implement something that clearly reflects what we mean? As mentioned earlier, abstract class represents an inheritance relationship in the Java language, and an inheritance relationship is essentially an "is-a" relationship. So for the concept of Door, we should use the abstarct class method to define it. In addition, AlarmDoor has an alarm feature that states that it is capable of fulfilling the behaviors defined in the alarm concept, so the alarm concept can be defined by interface. As follows:


abstract class Door{
abstract void open();
abstract void close() ;
}
interface Alarm{
void alarm();
}
class Alarm Door extends Door implements Alarm{
void open(){ ... }
void close(){ ... }
void alarm(){ ... }
}

This implementation can basically clearly reflect our understanding of the problem domain and correctly reveal our design intention. Its real abstract class represents "is - a relationship," said interface is like - a relationship, when the choice can be used as a basis, of course, it is based on the understanding of the problem domain, for example: if we think AlarmDoor in concept is essentially a alarm, at the same time have the ability to feel, will, in turn, so the definition of the way.

summary

Abstract class represents an inheritance relationship in the Java language. A class can only use an inheritance relationship once. However, one class can implement multiple interfaces.

2. Abstract class can have its own data members, and it can also have non-abstarct member methods, while interface can only have static data members that cannot be modified (that is, it must be static final, but the data members are generally not defined in interface), and all member methods are abstract.

3. Abstract class and interface reflect different design concepts. So abstract class is an "is-a" relationship, and interface is a" like-a" relationship.

Classes that implement abstract classes and interfaces must implement all of their methods. You can have non-abstract methods in an abstract class. There can be no implementation method in the interface.

5. The variables defined in the interface are public static final by default, and their initial values must be given, so they cannot be redefined or changed in the implementation class.

6. A variable in an abstract class is of friendly type by default, and its value can be redefined or reassigned in a subclass.

7. Methods in the interface are of public,abstract type by default.

conclusion

Abstract class and interface are two ways of defining abstract classes in the Java language that are very similar to each other. However, the choice of them often reflects the understanding of the conceptual nature of the problem domain and the correctness and rationality of the design intention, because they represent different relationships between concepts (although both can achieve the function of requirements). This is actually a kind of language usage, I hope the reader can understand.


Related articles: