Why extends is (a) August 31, 2003 Author harmful: neo
Overview Most good designers are like avoiding plagues to avoid using achievement inheritance (Extends). % 80 code should be written completely with Interfaces, without specific base classes. In fact, the four books of the four-handed design patterns have a lot of inheritance inheritance inheritance. This article describes why the designer has such a quirky idea. Extends is harmful; perhaps the level of Charles Manson is not, but it is poor enough to be avoided at any possible time. The four-man's design pattern spent a large part of the discussion with interface inheritance instead of reality. A good designer is in his code, mostly with Interface instead of a specific base class. This article discusses why the designer will have such a habit of quirky, and also introduce some interfab-based programming basis. Interface and Class once, I participated in a Java user group meeting. In the meeting, Jams Gosling (the father of Java) made a sponsor speech. In that unforgettable Q & A section, someone asked him: "If you re-construct java, what do you want to change?". "I want to abandon classes" he answered. After laughing, it explains that the real problem is not due to the Class itself, but implements inheritance (Extends). Interface inheritance (IMPLEMENTS relationship) is better. You should avoid inheritance as much as possible. Losing flexibility Why should you avoid inheritance? The first question is that the specific class name will be fixed to a particular implementation, and the change in the bottom layer has increased unnecessary difficulties. In the current agile programming method, the core is the concept of parallel design and development. Before you detail, you start programming. This technology is different from the form of traditional methods --- Traditional way is to design before the start of the coding - but many successful projects have proven that you can develop high quality code faster, relative to traditional according to the class method. However, the core developed in parallel is the flexibility. You have to write your code in a way so that the latest demand can be used as much as possible to merge into existing code. Slosing the features that you may need, you only need to achieve the characteristics you have clearly needed, and moderately vary. If you don't have this flexible, parallel development, it is impossible. The programming of Inteface is the core of the flexible structure. To illustrate why, let us see what will happen when using them. Consider the following code: [/ code] f () {linkedlist list = new linkedList (); // ... g (list);} g (LinkedList List) {list.add (...); g2 (List )} [/ Code] now, suppose a requirement for quick queries is proposed so that this LinkedList cannot be resolved. You need to use HashSet instead of it. In an existing code, the change is not able to locate because you need to modify f () also need to modify G () (it comes with a LinkedList parameter), and there is also a g () to pass the list to any code. Like the following to rewrite the code: [/ code] f () {Collection list = new linkedList (); // ... g (list);} g (collection list) {list.add (...); g2 (List)} [/ code] This modification of Linked List is HASH, which may only be simply used to replace New LinkedList (). that's it. There are no other places that need to be modified.
As another example, compare the following two paragraphs: [/ code] f () {Collection c = new hashset (); // ... g (c);} g (collection c) {for (Iterator i = C .iterator (); I.hasNext ()) do_something_with (i.next ());} [/ code] and [/ code] f2 () {Collection C = new hashset (); // ... g2 (c .iterator ());} G2 (Iterator i) {while (I.hasNext ()) DO_SOMETHING_WITH (I.Next ());} [/ code] G2 () method is now able to traverse Collection's derived, like you can The key value obtained from the MAP. In fact, you can write Iterator, which produces data, replaces a collection of Collection. You can write to iterator, it gets information from the test framework or file. This will have huge flexibility. Coupling For inheritance, a more critical issue is coupling - the irritated dependence is part of the program's dependence on another part. The global variable provides a classic example, which proves why strong coupling will cause trouble. For example, if you change the type of global variable, all functions of this variable may have been affected, so all of these code is checked, change, and retest. Moreover, all functions used to this variable are coupled to each other by this variable. That is, if a variable value is changed when it is difficult to use, a function may affect another function of another function. This issue is significantly hidden in multi-threaded programs. As a designer, you should work hard to minimize coupling relationships. You cannot eliminate coupling, because the method call from a class object to another class is a loosely coupled form. You can't have a program that doesn't have any coupling. However, you can minimize certain coupling by complying with the OO rules (most importantly, an object's implementation should be completely hidden in using his object). For example, an instance variable of an object (not a constant member domain) should always be private. I mean a period of time, no exception, constant. (You can occasionally use the protected method, but protected instance variable is awkward) The same reason you should not need Get / Set function - they are just a domain public just make people feel too complicated (although return to modification) Object rather than the basic type value is in some cases, in that case, the returned object class is a key abstraction when designing. Here, I am not angry. In my own work, I found a direct interrelationship between my OO method, fast code development and easy code implementation. Whenever I violate the center of OO principles, if I have hidden, I've rewritten that code (generally because the code is unmodable). I have no time to rewrite the code, so I follow those rules. I am concerned with the full use - I am not interested in clean reasons. Fragile base class problem now, let us apply coupling concept to inherit. In an inherited inheritance in Extends, the derived class is very close and base class coupled, and this tight connection is undesirable. The designer has applied nickname "fragile basic class problem" to describe this behavior. The basic class is considered to be fragile, because you modify the base class in the event of a safe situation, but when you inherit the class, new behaviors may cause the derived class to disorder.
You can't see the change of the base class by simple approach to the base class is secure; but you must also see (and test) all derived classes. Moreover, you must check all the code, which is also used in the base class and derived class object, because this code may be broken by the new behavior. A simple change for basic classes can cause the entire program to be unacceptable. Let us check the problem of fragile base classes and base classes. The following class extends the Java's ArrayList class to make it like a stack to operate: [/ Code] class Stack extends ArrayList {private int stack_pointer = 0; public void push (Object article) {add (stack_pointer , article);} public Object pop () {returnemove;} public void push_many (object [] articles) {for (int i = 0; i