ThinkingInJava notes-class regeneration (Chapter 6)

Source: Internet
Author: User

 

There are two types of regeneration:

Synthesize and create objects of the original class in the new class.

It creates a new class and treats it as a "type" of the existing class. We can take the form of the existing class as is and add new code to it, does not affect existing classes.

Because there are two classes-the base class and the category class, instead of the previous one, you may be confused when imagining the result object of the category class. From the external perspective, it seems that the new class has the same interface as the basic class, and can contain some additional methods and fields. However, inheritance is not just about copying basic class interfaces. When creating an object of the category class, it contains a "sub-object" of the base class ". This sub-object is like an object of the base class itself. Externally, the sub-objects of the base class have been encapsulated into objects of the category class.

Of course, basic class sub-objects should be correctly initialized, and there is only one way to ensure this: Execute initialization in the builder, by calling

With the base class builder, the latter has sufficient capabilities and permissions to perform initialization of the base class. Java will automatically insert

The call to the base class builder. The following example shows the application of Level 3 inheritance:

Java code

Public class Art {

Art (){

System. out. println ("art ");

}

}

 

Public class Drawing extends Art {

 

Drawing (){

System. out. println ("drawing ");

}

Public static void main (String [] args ){

Drawing drawing = new Drawing ();

}

}

 

Output result:

Art

Drawing

 

The above example has its own default builder; that is, they do not contain any independent variables. The compiler can easily call them because they are not stored.

The question of which independent variables are passed. If the class does not have the default independent variable, or you want to call a base class that contains the independent variable to build

You must explicitly write the calling code for the basic class. This is implemented using the super keyword and the appropriate list of independent variables, as shown below:

Java code

Class Game {

Game (int I ){

System. out. println ("Game constructor ");

}

}

 

Class BoardGame extends Game {

BoardGame (int I ){

Super (I );

System. out. println ("BoardGame constructor ");

}

}

 

Class Chess extends BoardGame {

Chess (){

Super (11 );

System. out. println ("Chess constructor ");

}

 

Public static void main (String [] args ){

Chess x = new Chess ();

}

}

 

Output result:

Game constructor

BoardGame constructor

Chess constructor

Although the compiler forces us to initialize the base class and requires us to do this at the beginning of the builder, it does not monitor us

Whether the member object is correctly initialized. Pay special attention to this.

 

One benefit of inheritance is that it supports "accumulative development", allowing us to introduce new code without causing errors to existing code. In this way

New errors are isolated from new code. By inheriting from a ready-made, functional class, and adding new data members and methods (and re-

Define existing methods), we can keep the existing code intact (and someone may still use it), without introducing their own programming errors.

Error. Once an error occurs, it must be caused by your new code. In this way, compared with modifying the subject of the existing code

The time and effort required for a positive error can be much less.

 

The most noteworthy part of inheritance is that it does not provide a method for the new class. Inheritance is an expression of the relationship between the new class and the basic class. Yes.

To sum up the relationship, "the new class belongs to one of the existing classes ".

This expression is not only a visual interpretation of inheritance, but also directly supported by languages. As an example, you can consider

One basic class named Instrument is used to represent an Instrument, and the other category is called Wind. Because inheritance means that all of the basic classes

Methods can also be used in Derived classes, so any messages we send to the basic class can also be sent to the messages class. If the Instrument class has one

The play () method is used by the Wind device. This means that we can definitely think that a Wind object is also one of the instruments.

Type. The following example shows how the compiler supports this concept:

 

Java code

Public class Instrument {

Public void play (){

System. out. println ("hello ");

}

Static void tune (Instrument I ){

I. play ();

}

}

 

Public class Wind extends Instrument {

 

Public static void main (String [] args ){

Wind wind = new Wind ();

Instrument. tune (wind );

}

}

Running result:

Hello

The most interesting in this example is the tune () method, which can accept an Instrument handle. However, in Wind. main (), the tune () method

It is called by assigning a Wind handle to it. Java is especially strict with the type check, so you may be surprised that

What kind of method can receive another type? However, we must realize that a Wind object is also

Instrument object. In addition, there is no way for an Instrument (Instrument) that is not in the Wind to be called by tune. In

In tune (), the Code applies to instruments and anything derived from instruments. Here we will begin with a Wind sentence

The act of converting a handle into an Instrument handle is called "upstream Styling ".

 

 

Because the direction of the shape is from the category class to the base class, the arrow is facing up, so it is usually called "upstream shape", that is, Upcasting. Upstream

Type is certainly safe, because we are from a more special type to a more general type. In other words, the category class is a super

Set. It can contain more methods than the base class, but it contains at least the methods of the base class. The class interface may output

The only problem is that it may lose methods, rather than winning them. This is when there is no clear shape or other special logo

Note: The reason why the compiler allows the shape extension is true.

 

Description of final keywords in inheritance:

Final data

(1) compile-time constant, which will never change

(2) A value initialized at runtime. We do not want it to change.

Java code

Final int s = 1; // s is a constant

Final Object obj = new Object (); // obj is an unchangeable handle, but the internal variable of obj can be changed.

Final int s; // s is a constant, but must be initialized before use

Void method (final int s) {}// when calling a method, s gets a value, but this value is read-only in the method.

 

Final Method

The final method may be used for two reasons. The first is to lock the method to prevent any inheritance class from changing its original meaning. When designing a program, you can do this if you want the behavior of a method to remain unchanged during the inheritance period and cannot be overwritten or rewritten.

The second reason for using the final method is the efficiency of program execution. After a method is set to final, the compiler can put all calls to that method into "embedded" calls. As long as the compiler finds a final method call, it will (based on its own judgment) Ignore the General Code insertion method used to execute the method call mechanism (push the independent variables into the stack; jump to the method code and execute it; jump back; clear the stack independent variable; and finally process the returned value ). Instead, it replaces the method call with a copy of the actual code in the method body. This avoids system overhead during method calls. Of course, if the method size is too large, the program will become swollen and may not be able to achieve any performance improvement caused by embedded code. Because any improvement is offset by the time spent in the method. The Java compiler can automatically detect these situations and "wisely" decide whether to embed a final method. However, it is best not to fully trust the compiler to make all the judgments correctly. Generally, you should consider setting a method as final only when the amount of code for the method is very small or you want to explicitly prohibit the method from being overwritten.

All private methods in the class are automatically final. Since we cannot access a private method, it will never be overwritten by other methods (if forced to do so, the compiler will give an error message ). You can add a final indicator for a private method, but cannot provide any additional meaning for that method.

Final class

After a class is defined as final, the result is that inheritance is not allowed-there are no more restrictions. However, because it prohibits inheritance, all methods in a final class are final by default. Because they cannot be overwritten at this time. Therefore, the compiler has the same efficiency choice as we explicitly declare a method as final. You can add a final indicator to a method in the final class, but this does not make any sense.

Class loading sequence:

If the base class contains another base class, the other base class is loaded immediately, and so on. Next, perform static initialization in the root base class, and then in the next category class, and so on. It is critical to ensure this order, because the initialization of the category class may depend on the correct initialization of the base class members.

 

Summary:

Whether inherited or merged, we can create a new type based on the existing type. However, in typical cases, we synthesize existing types of "regeneration" or "reuse" to use them as part of the basic implementation process of new types. However, if you want to implement "regeneration" of interfaces, you should use inheritance. Because the derived or derived classes have interfaces of the basic classes, they can be "uplinked" as the basic classes. This is vital to the problem of the polymorphism that will be discussed in the next chapter.

Although inheritance has been particularly emphasized in object-oriented programming, it is best to consider the adoption of synthesis technology when starting a design. Inheritance technology should be considered only when necessary (this issue will be discussed in the next chapter ). Merging is more flexible. However, by applying inheritance techniques to your member types, you can accurately change the types of member objects at runtime, thereby changing their behavior.

Although it is of great help for rapid project development to achieve code regeneration through synthesis and inheritance. However, before allowing other programmers to fully rely on it, they generally want to redesign their class structure. Our ideal class structure should be that each class has its own specific purpose. They cannot be too large (for example, if there are too many integrated functions, it is difficult to achieve its regeneration), and cannot be too small (as a result, they cannot be used by themselves, or new features cannot be added ). The final implemented classes should be able to be easily regenerated.

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.