Home Java javaTutorial Detailed explanation of composite mechanism in Java

Detailed explanation of composite mechanism in Java

Sep 09, 2017 pm 01:21 PM
java mechanism Detailed explanation

This article mainly introduces relevant information about the detailed examples of composite mechanism in Java. I hope that through this article, everyone can understand the difference between inheritance and composite and apply the composite mechanism. Friends in need can refer to it

Detailed explanation of examples of composite mechanisms in java

The defects of inheritance

The defects of inheritance are caused by its overly powerful functions . Inheritance makes the subclass dependent on the implementation of the superclass. From this point of view, it does not comply with the principle of encapsulation.
Once the superclass changes with a version release, the subclass may be broken, even if its code has not changed at all.

In order to explain more specifically, assuming that we are using HashSet in our program now, we need to add a function to count how many elements have been added to this HashSet since it was created.

Without knowing the flaws of inheritance, we designed a class that inherited HashSet, added an attribute addCount for statistics, and overridden the add and addAll methods. In the method Modify the value of addCount,

The code is as follows:


public class InstrumentedHashSet<E> extends HashSet<E> { 
  // The number of attempted element insertions 
  private int addCount = 0; 
 
  public InstrumentedHashSet() { 
  } 
 
  public InstrumentedHashSet(int initCap, float loadFactor) { 
    super(initCap, loadFactor); 
  } 
 
  @Override public boolean add(E e) { 
    addCount++; 
    return super.add(e); 
  } 
 
  @Override public boolean addAll(Collection<? extends E> c) { 
    addCount += c.size(); 
    return super.addAll(c); 
  } 
 
  public int getAddCount() { 
    return addCount; 
  } 
 
}
Copy after login

This class looks reasonable, but it does not work properly. Execute this paragraph Code:


public static void main(String[] args) { 
  InstrumentedHashSet<String> s = 
    new InstrumentedHashSet<String>(); 
  s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));   
  System.out.println(s.getAddCount()); // expect 3 but 6 
}
Copy after login

Because only three elements were inserted, we expected the getAddCount method to return 3, but in fact it returned 6. What went wrong?

In fact, within HashSet, the addAll method is implemented based on the add method. Therefore, using addAll to add three elements will call addAll once and add three times.
Looking at our overridden method, we will understand why getAddCount returns 6.

Of course, you will say that since HashSet is implemented in this way, then we don’t need to override the addAll method. Yes, that's right.

But although this can work normally, its correctness depends on the fact that the addll method of HashSet is implemented on the add method.

Once the super class modifies the implementation details, our functions may be affected.

In general, inheritance has three natural flaws, which will make the software very fragile:

1) If the subclass calls the method of the parent class, then it will It forms a dependency on the parent class. Once the parent class is changed, the subclass may not work properly.
2) If the parent class adds a new method, and the subclass happens to already provide a method with the same signature but a different return value, then the subclass will not be able to compile.
3) Using inheritance when it should not be done will expose unnecessary APIs to subclasses. In this regard, the Java platform has made mistakes. A typical example is that Properties inherits HashTable, which is unreasonable. The property list is not a hash table, but the Properties in the Java code inherits HashTable. As a result, after the user creates a Properties instance, there is a put There are two methods, setProperties and getProperties. The put and get methods should not be exposed to users.
Because in Properties, both key and value should be String, and HashMap can be other types or even objects.


public class TestProperty { 
  public static void main(String[] args) { 
    Properties properties = new Properties(); 
    properties.setProperty("aaa", "aaa"); 
    properties.put("aaa", new TestPropertyObj()); 
    System.out.println(properties.getProperty("aaa")); // null 
    System.out.println(properties.get("aaa")); // com.hzy.effjava.chp3.item16.TestProperty$TestPropertyObj@5f4fcc96 
  } 
  static class TestPropertyObj { 
     
  } 
}
Copy after login

Composite alternatives to inheritance

The previous section talked about the shortcomings of inheritance, this one Let us take a look at the solution to this problem - compounding.

First we need a class that holds a Set object. This class implements the Set interface. The implementation method calls the corresponding method of the Set object held, so we also call it forwarding. Class:


public class ForwardingSet<E> implements Set<E> { 
  private final Set<E> s; 
  public ForwardingSet(Set<E> s) { this.s = s; } 
 
  public void clear()        { s.clear();      } 
  public boolean contains(Object o) { return s.contains(o); } 
  public boolean isEmpty()     { return s.isEmpty();  } 
  public int size()         { return s.size();   } 
  public Iterator<E> iterator()   { return s.iterator(); } 
  public boolean add(E e)      { return s.add(e);   } 
  public boolean remove(Object o)  { return s.remove(o);  } 
  public boolean containsAll(Collection<?> c) 
                  { return s.containsAll(c); } 
  public boolean addAll(Collection<? extends E> c) 
                  { return s.addAll(c);   } 
  public boolean removeAll(Collection<?> c) 
                  { return s.removeAll(c);  } 
  public boolean retainAll(Collection<?> c) 
                  { return s.retainAll(c);  } 
  public Object[] toArray()     { return s.toArray(); } 
  public <T> T[] toArray(T[] a)   { return s.toArray(a); } 
  @Override public boolean equals(Object o) 
                    { return s.equals(o); } 
  @Override public int hashCode()  { return s.hashCode(); } 
  @Override public String toString() { return s.toString(); } 
}
Copy after login

Then, we can design a class with statistical functions. We only need to inherit the forwarding class we just created, and then the statistical logic code Just write:


public class InstrumentedSet<E> extends ForwardingSet<E> { 
  private int addCount = 0; 
 
  public InstrumentedSet(Set<E> s) { 
    super(s); 
  } 
 
  @Override public boolean add(E e) { 
    addCount++; 
    return super.add(e); 
  } 
  @Override public boolean addAll(Collection<? extends E> c) { 
    addCount += c.size(); 
    return super.addAll(c); 
  } 
  public int getAddCount() { 
    return addCount; 
  } 
 
  public static void main(String[] args) { 
    InstrumentedSet<String> s = 
      new InstrumentedSet<String>(new HashSet<String>()); 
    s.addAll(Arrays.asList("Snap", "Crackle", "Pop"));   
    System.out.println(s.getAddCount()); 
  } 
}
Copy after login

This implementation method avoids all the problems mentioned in the previous section. Since inheritance is not used, it does not depend on the super class. Implementation logic, there is no need to worry about the impact of new methods added to the super class on us.

And there is another advantage of writing this way. This class can add statistical functions to all classes that implement the Set interface, not just HashSet, but also other Sets such as TreeSet.

In fact, this is the decoration mode. InstrumentedSet modifies Set and adds a counting attribute to it.

Summary

Inheritance will destroy the encapsulation of the class, making the subclass very fragile and easily damaged.

Use the composite method to modify the super class to make the subclass more robust and more powerful.

The above is the detailed content of Detailed explanation of composite mechanism in Java. For more information, please follow other related articles on the PHP Chinese website!

Statement of this Website
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn

Hot AI Tools

Undresser.AI Undress

Undresser.AI Undress

AI-powered app for creating realistic nude photos

AI Clothes Remover

AI Clothes Remover

Online AI tool for removing clothes from photos.

Undress AI Tool

Undress AI Tool

Undress images for free

Clothoff.io

Clothoff.io

AI clothes remover

AI Hentai Generator

AI Hentai Generator

Generate AI Hentai for free.

Hot Article

R.E.P.O. Energy Crystals Explained and What They Do (Yellow Crystal)
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Best Graphic Settings
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. How to Fix Audio if You Can't Hear Anyone
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Chat Commands and How to Use Them
4 weeks ago By 尊渡假赌尊渡假赌尊渡假赌

Hot Tools

Notepad++7.3.1

Notepad++7.3.1

Easy-to-use and free code editor

SublimeText3 Chinese version

SublimeText3 Chinese version

Chinese version, very easy to use

Zend Studio 13.0.1

Zend Studio 13.0.1

Powerful PHP integrated development environment

Dreamweaver CS6

Dreamweaver CS6

Visual web development tools

SublimeText3 Mac version

SublimeText3 Mac version

God-level code editing software (SublimeText3)

Perfect Number in Java Perfect Number in Java Aug 30, 2024 pm 04:28 PM

Guide to Perfect Number in Java. Here we discuss the Definition, How to check Perfect number in Java?, examples with code implementation.

Random Number Generator in Java Random Number Generator in Java Aug 30, 2024 pm 04:27 PM

Guide to Random Number Generator in Java. Here we discuss Functions in Java with examples and two different Generators with ther examples.

Weka in Java Weka in Java Aug 30, 2024 pm 04:28 PM

Guide to Weka in Java. Here we discuss the Introduction, how to use weka java, the type of platform, and advantages with examples.

Smith Number in Java Smith Number in Java Aug 30, 2024 pm 04:28 PM

Guide to Smith Number in Java. Here we discuss the Definition, How to check smith number in Java? example with code implementation.

Java Spring Interview Questions Java Spring Interview Questions Aug 30, 2024 pm 04:29 PM

In this article, we have kept the most asked Java Spring Interview Questions with their detailed answers. So that you can crack the interview.

Break or return from Java 8 stream forEach? Break or return from Java 8 stream forEach? Feb 07, 2025 pm 12:09 PM

Java 8 introduces the Stream API, providing a powerful and expressive way to process data collections. However, a common question when using Stream is: How to break or return from a forEach operation? Traditional loops allow for early interruption or return, but Stream's forEach method does not directly support this method. This article will explain the reasons and explore alternative methods for implementing premature termination in Stream processing systems. Further reading: Java Stream API improvements Understand Stream forEach The forEach method is a terminal operation that performs one operation on each element in the Stream. Its design intention is

TimeStamp to Date in Java TimeStamp to Date in Java Aug 30, 2024 pm 04:28 PM

Guide to TimeStamp to Date in Java. Here we also discuss the introduction and how to convert timestamp to date in java along with examples.

Java Program to Find the Volume of Capsule Java Program to Find the Volume of Capsule Feb 07, 2025 am 11:37 AM

Capsules are three-dimensional geometric figures, composed of a cylinder and a hemisphere at both ends. The volume of the capsule can be calculated by adding the volume of the cylinder and the volume of the hemisphere at both ends. This tutorial will discuss how to calculate the volume of a given capsule in Java using different methods. Capsule volume formula The formula for capsule volume is as follows: Capsule volume = Cylindrical volume Volume Two hemisphere volume in, r: The radius of the hemisphere. h: The height of the cylinder (excluding the hemisphere). Example 1 enter Radius = 5 units Height = 10 units Output Volume = 1570.8 cubic units explain Calculate volume using formula: Volume = π × r2 × h (4

See all articles