Does inheritance in C + + break encapsulation?

Source: Internet
Author: User

 Class inheritance is statically defined at compile time and can be used directly, and class inheritance can easily change the implementation of the parent class. But class inheritance also has some shortcomings. First, because inheritance is defined at compile time, it is not possible to change the implementation inherited from the parent class at run time. To make things worse, the parent class usually defines at least part of the behavior of the subclass, and any changes to the parent class can affect the behavior of the child class. If the inherited implementation is not suitable for solving the new problem, the parent class must be overridden or replaced by another more appropriate class. This dependency limits flexibility and ultimately limits reusability. In the first example, we use an inheritance-based framework, and we can see that it is difficult to maintain and extend. Abstract class Abstractexampledocument {//Skip some code ... public void output (Example structure) {if (null! = STRUCTU RE) {THIS.FORMAT (structure);}} protected void Format (Example structure); In the second example, we use the framework of object-based composition technology, where each object's tasks are clearly separated, and we can replace and extend the format class without thinking about anything else. Class Defaultexampledocument {//Skip some code ... public void output (Example structure) {Exampleformatter formatter = (Exampleformatter) Manager.lookup (roles.formatter); if (null! = structure) {FORMATTER.FORMAT (structure);}} Here, a component creation pattern similar to the "abstract factory" is used, which takes the component creation process to the manager, and Exampleformatter is the abstract parent of all formats, separating the mutable part from the immutable part "separating the mutable part from the immutable part" is a third principle of object-oriented design. If we use the inherited multiplexing technique, we can define immutable parts in the abstract base class, and the subclasses will implement the variable parts, and the immutable parts do not need to be defined repeatedly and are easy to maintain. If we use the reuse technique of object composition, we can define the immutable parts, while the mutable ones can be implemented by different components and dynamically configured at runtime, as needed. In this way, we have more time to focus on the variable parts. For theAs for the combination technology, each component only completes relatively small function, the coupling between the two is relatively loose, the reuse rate is high, and by combining, the new function can be obtained. Reduce the length of the method usually, our method should be only as few as possible, the method of too long will be difficult to understand, and if the method is too long, it should be redesigned. This can be summed up in the following principles: ☆ 30 Second principle: If another programmer is unable to understand what your function does in 30 seconds, how to do it, and why to do so, then it means that your code is difficult to maintain and must be improved; ☆ One-screen principle: If a function's code is longer than a screen, then perhaps the function is too long and should be broken into smaller sub-functions; ☆ A line of code is as short as possible, and one line of code is guaranteed to do just one thing: that seemingly tricky verbose code only increases the difficulty of code maintenance. To eliminate case/if statements, try to avoid having a judgment statement in your code to test whether an object is an instance of a particular class. In general, if you need to do this, re-engineering may be useful. I encountered this problem at work: when we use Java FOR XML parsing, we map a Java class to each tag, using the SAX (simple XML interface api:simple API for XML) model. As a result, a large number of judgment statements are repeated in the code to test the current label type. To do this, we redesigned the DTD (document type definition: Doc type definitions), added a fixed attribute to each label: ClassName, and redesigned the interface of each tag-mapped Java class to unify the operation of each object: AddElement (Element aelement); Add child element AddAttribute (string attname, string attvalue); Adds a property; it completely eliminates all of the judgment statements that test the current label type. Each object is passed Class.forName (AElement.attributes.getAttribute ("classname")). Newinstence (); Dynamic creation, reducing the number of parameters there are a number of parameters required to pass the method, often difficult to read. We can encapsulate all the parameters into an object to complete the object's delivery, which also facilitates error tracing. Many programmers because too many layers of object wrapping have an impact on system efficiency. Yes, but, compared with the benefits it brings, we prefer to do the packing. After all, "encapsulation" is also one of the basic features of OO, and "every object completes as little (and as simple) a function as possible" is also a basic principle of oo. The top layer of the class hierarchy should be abstractClass in many cases, providing an abstract base class is advantageous for the characterization of the extension. Since most functions and behaviors are defined in the abstract base class, it makes it easier to understand what the interface designer intends to do. Since Java does not allow "multiple inheritance", inheriting from an abstract base class, it is no longer possible to inherit from another base class. Therefore, it is a good idea to provide an abstract interface (interface), a class can implement multiple interfaces, thus simulating the implementation of "multi-Inheritance", for the design of the class provides greater flexibility. Minimizing the direct access to variables the encapsulation principle of data should be normalized, not exposing the properties of one class to other classes, but should protect them by means of access, which helps to avoid ripple effects. If the name of a property changes, you just need to modify its access method instead of modifying all the relevant code. Subclasses should be attributed to special functions if a subclass simply turns a component into a Component manager instead of implementing an interface function, or overloads a feature, you should use an external container class instead of creating a subclass. Recommendation: Class hierarchy chart, not too deep; For example: The following interface defines the functionality of a component: sending a message; Class transceiver implements the interface, and its subclass pool simply manages multiple transceiver objects without providing its own interface implementation. It is recommended to use combination instead of inheritance! Public interface itransceiver{Public abstract send (String msg), public class transceiver implements Itransceiver {Publ IC Send (String msg) {System.out.println (msg);}} Implementation of the use of inheritance public class pool extends transceiver{private List Pool = new Vector (), public void Add (transceiver atranscei ver) {pool.add (atransceiver);} public transceiver get (int index) {pool.get (index);}} The implementation of the use combination method public class Pool {private List pool = new Vector (), public void Add (transceiver Atransceiver) {Pool.add (ATra Nsceiver); } public transceiver get (int index) {pool.get (index);}} Split oversized class if a class has too many methods (more than 50), then it may have to do too much work, and we should try to split its functionality into different classes, similar to Rule four. Objects that have a distinct effect should be split in the process of building, and you sometimes encounter the problem of having different views of the same data. Some properties describe how data structures are generated, and some properties describe the structure itself. It is a good idea to split the two views into different classes, and from the class name you can distinguish between different views. Class domain, method should also have the same consideration! Minimizing the implicit delivery of parameters two ways to handle the same data (domain) within a class does not mean that they are processing the data (domain). In many cases, this data (domain) should be used as a method's parameter input, rather than as a direct access, especially in the design of a tool class. For example: public class test{private List pool = new Vector (), public void Testadd (String str) {pool.add (str),} public Object T Estget (int index) {pool.get (index);}} Each of the two methods operates on the list object pool, but, in fact, we may just want to test the different implementations of the list interface vectors, ArrayList, and so on. So, the code should write this: public class test{private List pool = new Vector (); public void Testadd (List pool, String str) {pool.add (str) ; Public Object Testget (List pool, int index) {pool.get (index);}}

Does inheritance in C + + break encapsulation?

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.