My thinking in Java Study Notes (10)

Source: Internet
Author: User
Chapter 6 reuse classes
In a process-oriented language, repeated use of code is just a simple copy of code to achieve the purpose of repeated use. In an Object-Oriented Java program, code reuse is mainly reflected in 2 points.
1. Use the existing class in the new class, which is called a "Combination ". However, this reuse method only simply repeat some code functions, rather than reusing them.
2. Let the new class become a class of the existing class, and add new functions as needed without changing the original class. This method is called "inheritance ".
Combination syntax
In fact, we have used a lot of combinations in the previous example. We only need to place the object handle in the class to be a combination!
Class compostion
{
Private string S;
Compostion ()
{
System. Out. println ("compostion ()");
S = new string ("hello ");
}
Public String tostring ()
{
Return S;
}
}
Public class test
{
Compostion C; // object handle
Int I;
Public void show ()
{
System. Out. println ("Int =" + I );
System. Out. println ("compostion =" + C );
}
Public static void main (string ARGs [])
{
Test T = new test ();
T. Show ();
}
}
Each object of the non-basic data type has a tostring () method. This function is used to convert compostion to a string, the base data type of the class added to other strings is initialized as the default value, and the object handle is initialized as null. If you want to use this handle, remember to initialize it; otherwise, a null pointer error will occur!
Inheritance
Inheritance is an extremely important part of the Java language. It is implemented using the keyword extends, so that the subclass can automatically obtain all the member data and functions of the parent class. All classes in Java, even the classes you have defined or want to define, are inherited from the object class and implicitly inherited within the compiler.
Class base
{
Int I = 10;
Public void show ()
{
System. Out. println ("base method ");
}
Public static void main (string ARGs []) // Java allows the class in the same file to have its own main ()
{
New base (). Show ();
}
}
Class derived extends base // inheritance
{
Public void show () // overwrites the base function
{
System. Out. println ("derived method ");
Super. Show (); // call the base function
}
Public void newmethod () // the newly added function in the subclass
{
System. Out. println (I); // print the data in the base.
}
Public static void main (string ARGs [])
{
Derived d = new derived ();
D. Show ();
D. newmethod ();
}
}
Base Initialization
When a subclass is initialized, the system first initializes the inherited parent class. The Java compiler calls the constructor of the parent class before calling the subclass constructor.
Class base
{
Base ()
{
System. Out. println ("base method ");
}

}
Class derived extends Base
{
Derived ()
{
// Super (); the system automatically adds a call to the parent class.
System. Out. println ("derived method ");
}
Public static void main (string ARGs [])
{
Derived d = new derived ();
}
}
If your parent class is a class with a reference, the compiler will not automatically call the constructor. You must use super to call the constructor. Otherwise, the system will encounter errors.
Class base
{
Base (string S)
{
System. Out. println (s );
}

}
Class derived extends Base
{
Derived ()
{
Super ("base method"); // must be the first line of the constructor statement
System. Out. println ("derived method ");
}
Public static void main (string ARGs [])
{
Derived d = new derived ();
}
}
Compatible combination and inheritance
Sometimes, we use not only combinations but also inheritance when writing classes.
Select between combination and inheritance
If you only want to use the functions of the existing class in the new class and hide the implementation details, it is best to use a combination.
If you want to develop a special version for the existing class, it would be better to inherit it.
If your existing classes and new classes are a (is a) Relation of is a, use inheritance. If it is an has a (has a) relation, use a combination.
Protected
Let's review the meaning of protexted: Inherit the subclass of this class, you can access the members of this class, and other classes in a package are friendly
Progressive Development
One of the advantages of inheritance is that it supports progressive development. In this development mode, you can add new program code in the program, but it does not affect the code of the parent class.
Upward Transformation
Because of the inheritance relationship, all functions of the parent class can be used in the subclass, and any messages sent to the parent class can also be sent to the subclass.
Class base
{
Protected void show ()
{
System. Out. println ("base method ");
}
Protected void Getsomeone (Base B)
{
B. Show ();
}
}
Class derived extends Base
{
Public static void main (string ARGs [])
{
Derived d = new derived ();
D. Getsomeone (d );
}
}
Note that in the Getsomeone function definition, we define that he can accept only one base class handle, but he actually accepts the subclass handle. Although the subclass is not the same as the parent class, it is a type of parent class after all. Therefore, the function applicable to the parent class is also applicable to the subclass, we call this method of transforming sub-classes into parent classes to upward transformation upcasting.
Class base
{
Public void methodone ()
{
System. Out. println ("base. methodone ");
}
Public void methodtwo ()
{
System. Out. println ("base. methodtwo ");
}
}

Class derived extends Base
{
Public void methodone ()
{
System. Out. println ("derived. methodone ");
}
Public void methodtwo ()
{
System. Out. println ("derived. methodtwo ");
}
Public void methodnew ()
{
System. Out. println ("derived. methodnew ");
}
Public static void main (string [] ARGs)
{
Base d = new derived ();
D. methodone (); // although it has been transformed to base, the called function is still a base class function, showing derived. methodone
D. methodtwo (); // same as above
// D. methodnew (); the unique function of the subclass is lost because it has been transformed upwards.
}
}
Why do we need an upward transformation?
A subclass is a superset of the parent class. Therefore, the subclass contains at least the functions in the parent class and may contain more. However, the upward transformation will cause the subclass to lose the method different from the parent class, and the upward transformation must be safe, because this is changed from a special type to a general type.
Combination vs inheritance
It is the best time to use inheritance when you need to transform upwards.
Keyword final
What is final? That is, the meaning of "final", that is, the meaning that cannot be changed. Here we will discuss final in 3: data, method, Class
Final data
Final data is fixed and constant data is called constants. It is useful because it
1. It can be a constant that never changes during compilation. Compile-time constants can execute some calculations during the compile-time period to reduce the burden on the execution period. Such constants must be of the basic data type and be decorated using final. The initial values must be specified.
2. It can be initialized during the execution period, but you don't want to change it any more.
If a data has both static and final data, it will have an unchangeable storage space. When the final is used for objects, the final keeps the handle unchanged and cannot point to other objects again. However, the object itself can be changed, this is different from the final data type that cannot change its value.
Class Value
{
Int I = 1;
}
Class finaldata
{
// Constant during compilation
Final int I = 10;
Static final int II = 20;
// Typical Constants
Public static final int IIi = 30;
// Execution period constant
Final int iiii = (INT) (math. Random () * 20 );
Static final int IIIII = (INT) (math. Random () * 20 );

Value v = new value ();
Final value VV = new value ();
Static final value vvv = new value ();
// Array
Final int [] A = {1, 2, 3, 4, 5, 6 };

Public void show (string ID)
{
System. Out. println (ID + ":" + "iiii =" + iiii + ", IIIII =" + iiiii );
}
Public static void main (string [] ARGs)
{
Finaldata FD = new finaldata ();
// FD. I ++; the value cannot be changed.
FD. vv. I ++; // final object can change its object Value
FD. V = new value (); // non-final
For (INT I = 0; I <FD. A. length; I ++)
FD. A [I] ++; // The final object can change its value.
// FD. VV = new value (); // the handle of the final object cannot change the referenced object.
// FD. vvv = new value (); // the handle of the final object cannot change the referenced object.
// FD. A = new int [3]; // the handle of the final object cannot change the referenced object.

FD. Show ("FD ");
System. Out. println ("creat new finaldata ");
Finaldata NFD = new finaldata ();
FD. Show ("FD ");
NFD. Show ("NFD ");
}
}
/* Display FD: iiii = 2, IIIII = 3
Creat New finaldata
FD: iiii = 2, IIIII = 3
NFD: iiii = 1, IIIII = 3 */Because iiii is not static, the values for each operation are different. Static final data will only be initialized during loading, and will not be initialized every time a new object is generated.
Blank final
Final also allows the data member to be declared as final but not initialized. However, you must ensure that the data member is initialized before using the data member. The advantage of doing so is to ensure the constant immutability of data,
It can also generate different final data based on different objects, with greater flexibility.
Class finaltest
{
Final string S;
Finaltest (string S)
{
This. S = s;
System. Out. println (this. s );
}
Public static void main (string [] ARGs)
{
New finaltest ("hello ");
New finaltest ("bye ");
}
}
Final reference
When the final index is of the basic data type, its value cannot be changed. When it is an object, it is not allowed to change the pointer of the handle.
Final Functions
The final function has two meanings:
1. Lock the function. The subclass cannot be changed, that is, it cannot be overwritten.
2. Improve Execution efficiency for short Functions
Final and private
The private function in the class is actually a natural final function, because you cannot use the private function, and of course you cannot override this function. When you try to override this function, actually, I wrote a brand new function and added final to the private function, which is meaningless!
Final class
When you want to ensure that the class cannot be inherited, you need to use final. However, whether the class is final or not, the data member in the class can be either final or not.
Initialization and class loading
In Java, classes are loaded only when necessary. Generally, classes are first used and inherited. The so-called first use is not only used to generate objects, it may also be when a static function or data member is used. When class is used for the first time, it is also static initialization. When any static class members are loaded, they will be initialized separately according to the order they appear, and only one initialization will be performed.
Inheritance and initialization
The following program shows the sequence of inheritance and loading.
Class base
{
Int I = 10;
Int J;
Base () // 6. Execute the base constructor.
{
Show ("I =" + I + ", j =" + J );
J = 20;
}
Static int M = show ("static base. m init"); // 2. initialize static members for loading
Public static int show (string S)
{
System. Out. println (s );
Return 30;
}
}

Class derived extends Base
{
Int K = show ("derived. K init"); // 7. initialize the basic data type.
Derived () // 8. The data member initialization has been completed and the function is executed.
{
Show ("k =" + k );
Show ("J =" + J );
}
Static int n = show ("static derived. N init"); // 3. initialize static members for loading.
Public static void main (string [] ARGs) // 1. Enable the derived. Main () static method. The class derived is used, causing the loader to start. extends is found, so the base is loaded.
{
Show ("derived constructor"); // 4. After loading, run the program.
Derived d = new derived (); // 5. The base object is generated first due to the extends relationship.
}
}
Output/* Static base. m init
Static derived. N init
Derived Constructor
I = 10, j = 0
Derived. K init
K = 30
J = 20 */
Summary
Both inheritance and combination allow you to generate new classes based on existing classes. Use a combination to reuse a class to make it a part of the new class. inheritance is used for interface reuse. Because the subclass inherits the interface of the parent class, it can be transformed upwards, this is extremely important for polymorphism. It is recommended to use multiple combinations. The combination is elastic and the inheritance is flexible.

Exercise answers
In fact, the exercises in this chapter are not difficult. They are all about consolidating the exercises of knowledge points. If you do this carefully, you can certainly do it. You will not pay attention to reading books!
In the next chapter, my notes will show the object-oriented essence-polymorphism! Thank you for your attention and support!
 
Related Article

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.