[Java Study Notes] Chapter 5 inheritance of Java core technologies
Chapter 2 Inheritance
Using inheritance, You can construct a new class based on an existing class. Inheriting existing classes is to reuse (inherit) the methods and domains of these classes. You can also add new methods and domains.
Reflection.
5.1 superclass subclass
Use extends to construct a derived class
Class Manager extends Employee {Add method and domain override: override methods that are not suitable for derived classes in some base classes}
All inheritance types are public inheritance. That is, all the public and protected members remain in the original state, and the Private Members of the base class are still private. It cannot be accessed by a member of a derived class.
(In c ++, private inheritance or protection inheritance will convert both public and protected members into private or protected members of the derived class)
Base class, parent class, And superclass: inherited class
Derived class, child fatigue, subclass: New Class
Use super to call methods that are overwritten by the base class. Unlike this, super is only a special keyword used to indicate the compiler to call a superclass method.
Use super to call the constructor super (parameter list...) of the base class. Because the derived class cannot call the private domain of the base class, all constructors need to call the constructor to initialize the private domain.
If the derived class does not show that the superclass constructor is called, the default constructor of the base class is automatically called. If there is no constructor without parameters and no other constructor that explicitly calls the superclass, the Java compiler reports an error.
Class Employee {private double salary; public double getSalary (){...} public Employee (double x ){...}} class Manager extends Employee {private double bonus; public void setBonus (double B ){...} public double getSallary () {// return salary + bonus; cannot run, salary is the private variable of the base class // return bonus + getSalary (); cannot run, the derived class overwrites the getSalary method return bonus + super of the base class. getSalary (); // call the getSalary method of the base class through super} public Manager (double B) {super (B); // call the base class constructor }}
5.1.1 coverage
The method with the same signature as that in the superclass In the subclass is overwrite.
Because the method signature includes the method name and parameter list, and does not include the return value, the return types of all override methods can be child types of the original type. Ensure compatibility.
When overwriting a method, the subclass method cannot be lower than the visibility of the superclass method. Especially if the superclass method is public, the subclass method must be declared as public.
The final method in the superclass cannot be overwritten.
You can use @ Override to mark the method to indicate that it needs to overwrite the superclass. If there is no suitable method in the superclass to be overwritten, an error is returned. Otherwise, the programmer may think that the superclass method is overwritten, but it is actually a new method that only belongs to the subclass.
@Override public boolean equals(Employee other)
5.1.2 inheritance level
Inheritance is not limited to one level. But does not support multi-inheritance.
A set of all classes derived from a public superclass is called an inheritance level.
The path from a specific class to its ancestor is called the inheritance chain of this class.
5.1.3 Polymorphism
An object variable can indicate a variety of actual types of phenomena called polymorphism.
An ancestor object can reference any descendant object of different levels, but cannot assign a superclass reference to a subclass (forced type conversion is required ).
The reference of the subclass array can be converted into the reference of the super class array without the need for forced type conversion. In this case, all arrays should keep in mind the element types they are created for, and be responsible for supervising the storage of compatible type references to arrays.
Is-a rule: 4.1.3. Each object of a subclass is also a superclass object. Otherwise, any superclass object can be replaced by a subclass object.
5.1.4 dynamic binding
Dynamic binding is used to automatically select the method to be called according to the actual type of the privacy parameter during runtime.
When calling object methods:
1: The Compiler first obtains all candidate methods that may be called. Obtain the declared type C and method name f by viewing the object. There may be multiple f methods with the same name but different parameters, the compiler will list the f methods in class C and the f methods whose access attribute is public in Class C.
2: The Compiler checks the list of parameters provided when a method is called. If there is a perfect match among all the methods named f, select this method. This process is called reload parsing.
3: If it is a private static final method or constructor, the compiler can accurately know which method should be called. This call method is called static binding. When the called method depends on the actual type of the implicit parameter and is bound at runtime, it is called dynamic binding.
4: when the program runs and the dynamic binding method is used, the virtual machine must call the method of the class that is most suitable for the actual type of the referenced object.
5.1.5 final classes and Methods
Block inheritance and use the final modifier.
If you use the final modifier class, this class is called the final class and cannot be inherited. If you use the final modifier method, this method cannot be overwritten.
If a class is declared as final, only the methods in the class are automatically called final, excluding the domain.
The domain can also be declared as final. For the final domain, the value cannot be changed after the object is constructed.
The main purpose of declaring methods or classes as final is to ensure that they do not change the semantics in the subclass.
5.1.6 forced type conversion
Manager boss = (Manager)employee;
The only reason for type conversion is that all functions of the object are used after the actual type of the object is temporarily ignored.
Type conversion is required when a superclass is referenced to a subclass variable.
If the conversion fails, an exception is thrown, instead of generating a null object like C ++.
Use the instanceof operator to determine whether the conversion is successful:
if(employee instanceof Manager){ boss=(Manager)employee; ...}
5.1.7 abstract class
abstract class Person{ .... public abstract String getDescription();}
A method has different override implementations in the derived class. If the ancestor class is not used as a specific class, you can declare this method as an abstract method to ignore the specific implementation in the ancestor class.
Abstract METHODS act as placeholder, and their implementations are in sub-classes.
An extended abstract class can be selected in two ways. One is to define partial or abstract methods in the subclass, so that the subclass must be marked as an abstract class. The other is to define all abstract methods, in this way, the subclass is not abstract.
When a class contains one or more abstract methods, the class itself must be declared as abstract. Classes can be declared as abstract classes even if they do not contain abstract methods.
Abstract classes cannot be instantiated. They cannot create objects of abstract classes, but can reference non-Abstract subclasses.
In addition to abstract methods, abstract classes can also contain specific data and methods. We recommend that you try to put the common domains and methods (whether abstract or not) in the superclass (whether abstract or not.
Abstract methods are an important concept in the Java programming language. More abstract methods are displayed in the interface.
5.1.8 protected access
Some methods in the superclass allow access by the quilt class, or allow sub-class methods to access a domain of the superclass, these methods or fields can be declared as protected.
The subclass can only access the protected domain in its object, but does not need to access this domain in other super-class objects.
Exercise caution when using the protected attribute. Because the derived class can access the protected domain, if you need to modify the implementation of the class, you must notify all programmers who use this class, it violates the Data encapsulation principles advocated by OOP.
However, the protected method is useful for specifying methods that should be redefined in subclasses without providing general purpose.
5.1.9 access modifier
Private is only visible to this class
Public visible to all classes
Protected this package and all subclasses are visible
This package is visible without modification. The default value is
5.2 Object
The Object class is the ancestor of all Java classes, and each class is extended by it. If the superclass is not explicitly specified, the Object is considered as the superclass of the class.
Only the basic type is not an object.
// You can use Object-type variables to reference objects of any type: Object obj = new Employee (); // However, Object-type variables can only be used as common holders of various values, to perform specific operations on it, you also need to convert it to the original type: Employee em = (Employee) obj;
5.2.1 equals Method
Checks whether an object is equivalent to another object. In the Object, this method is used to determine whether two objects have the same reference.
If you re-define the equals method, you must re-define the hashCode method so that you can insert the object to the hash list.
For array fields, you can use the static Arrays. equals method to check whether the corresponding array elements are equal.
Java requires the equals method to have the following features:
1: Self-inverse. returns true for any non-null reference x, x. equals (x)
2: Symmetry. For any reference to x and y, if and only if y. equals (x) returns true, x. equals (y) also returns true.
3: pass-through. If x. equals (y) y. equals (z) returns true for any reference to x y z, x. equals (z) returns true.
4: consistency. If the objects referenced by x and y do not change, repeated calls to x. equals (y) should return the same result.
5: For any non-null reference x, x. equals (null) should return false
Suggestions for the perfect equals method:
1: The display parameter is named otherObject. You need to convert it to another variable named other later. 2: Check whether this and otherObject reference the same object if (this = otherObject) return true; this statement is only an optimization, the cost for calculating this equation is much lower than that of the domains in comparison classes. 3: checks whether otherObject is null. If it is null, false is returned. This check is necessary. If (otherObject = null) return false; 4: compare whether this and otherObject belong to the same class. If the equals semantics changes in each subclass, use getClass to detect if (getClass ()! = OtherObject. getClass () return false; if all sub-classes have unified semantics, use Instanceof Detection: if (! (OtherObject instanceof ClassName) returen false; 5: Convert otherObject to the corresponding class type variable: ClassName other = (ClassName) otherObject; 6: Compare the domains to be compared. Use = to compare the basic type fields, and use equals to compare the object fields. If all fields match, true is returned. Otherwise, false. If equals is defined in the subclass, the super. equals (other)
5.2.2 hashCode Method
Hash code is an integer value exported from an object. Not regular.
The hashCode method is defined in the Object class. Each Object has a default hash code whose value is the storage address of the Object.
The hash code of String is exported from the content.
If you re-define the equals method, you must re-define the hashCode method so that you can insert the object to the hash list.
It is best to use the null-safe method Objects. hashCode. If its parameter is null, 0 is returned.
The definitions of equals and hashCode must be consistent: If x. equals (y) returns true, x. hashCode () must be the same as y. hashCode.
Array fields can use Arrays. hashCode to calculate a hash code. This hash code consists of the hash code of the array element.
5.2.3 toString Method
Most toString methods should follow this format: class name [domain = Domain value,...]
The default toString of the array is printed according to the old format. [I @...] prefix [I indicates that it is an integer array and the content is not a string listed by element values. You can use Arrays. toString instead to generate an element string [2, 3...].
Multi-dimensional array uses Arrays. deepToString
5.3 Generic Array list 5.3.1 array list
Once the array size is determined, it is not easy to change it. You can use ArrayList.
ArrayList is a generic class that uses type parameters.
<> The type parameter in is not allowed to be the basic type.
The size of the array list differs significantly from the size of the array. If you allocate a storage space of 100 elements to the array, the array can have 100 null positions. The list of arrays with a capacity of 100 elements only has the potential to store 100 elements (in fact, more than 100 elements will be reallocated space). However, after initial initialization or initialization, the array list does not contain any element at all.
The efficiency of inserting and deleting arrays is low. Large tables should use linked lists.
// Construct an empty array list ArrayList <Employee> staff = new ArrayList <> (); // add a larger array automatically created when the internal array is full after calling add, and copy all objects to staff. add (new Employee (); // ensure that the array list can save a specified number of elements without re-allocating the storage. ensureCapacity (100); // returns the actual number of elements, equivalent to. lengthstaff. size (); // use the specified capacity to construct an empty array list ArrayList <Employee> staff = new ArrayList <> (100 ); // reduce the storage capacity of the array list to the current size of staff. trimToSize (); // create a list and copy it to the array. ArrayList <x> list = new ArrayList <> (); while (...) {x = ...; list . Add (x);} X [] a = new x [list. size ()]; list. toArray (a); // Insert at the nth position, and move the stff after n. add (n, e); // use the get and set methods to access or change array elements, rather than the [] method. // Replace the content of an existing I element with staff. set (I, harry); // obtain the I-th element: Employee e = staff. get (I); // remove the nth element Employee e = staff. remove (n );
5.3.2 compatibility between typing and the original array list
5.4 object wrapper
Converts a basic type to an object. All basic types have a corresponding class called the package.
Integer Long Float Double Short Byte Character Void Boolean
The class of the object wrapper is immutable. Once the wrapper is constructed, the value in the package cannot be changed. At the same time, the class of the object wrapper is still final, so their subclasses cannot be defined.
An array list of the basic type, such as an Integer, cannot be written as an ArrayList <int> or an ArrayList <Integer> list =...; the efficiency is much lower than that of an array.
List. add (3); will be automatically changed to list. add (Integer. valueOf (3); this change becomes automatically packed.
On the contrary, when an Integer object is assigned to an int value, it is automatically split.
Int n = list. get (I); will be translated into int n = list. get (I). intValue ();
Packing and unpacking are approved by the compiler, rather than virtual machines. The compiler inserts necessary method calls when generating the class bytecode. The VM only executes these bytecode.
// Convert the string to an Integer int x = Integer. parseInt (s); // modify the numeric value using the holder type each holder type contains a public domain value public static void triple (IntHolder x) {x. value = 3 * x. value ;}
5.5 Variable Parameter Quantity Method
public PrintStream printf(String fmt ,Object... args){ return format(fmt,args);}
Ellipsis... is part of the code, indicating that this method can receive any number of objects
Allow passing an array to the last parameter of the Variable Parameter Method
System. out. printf ("% d % s", new Object [] {new Integer (1), "widgets "});
Therefore, you can redefine an existing method with the last parameter as an array as a variable parameter without damaging any existing code.
Public static void main (String... args)
5.6 enumeration class
Public enum Size {SMALL, MEDIUM, LARGE, EXTRA_LARGE };
In fact, what type is defined as a class? There are exactly four instances. Try not to create new objects here.
When comparing values of the two enumeration types, you never need to call equals and directly use =
You can add constructors, methods, and fields to the enumeration type. The constructor is called only when the constructor constructs an American drama constant.
All enumeration types are subclasses of The Enum class,
// ToString returns the enumerated constant name Size. SMALL. toString () returns the inverse method of the string "SMALL" // valueOf toString Size s = Enum. valueOf (Size. class, "SMALL"); Sets s to Size. SMALL // values returns the array Size [] values = Size that contains all enumerated values. values (); // ordinal returns the position of the enumerated constant in the enum declaration, starting from 0 int I = Size. MEDIUM. ordinal (); // I = 1 // compareTo (E) returns a negative value before e in the relative order; this = e returns 0; returns a positive value after e
5.7 reflection
Programs capable of analyzing class capabilities are called reflection.
5.7.1 Class
During the running of the program, the Java runtime system clock maintains a type identifier called runtime for all objects. This information tracks the class to which each object belongs. The Class that saves the information is called Class.
A Class Object actually represents a type, which is not necessarily a type. For example, int Is not a class, but int. Class is a class object.
Employee e;... // getClass returns an instance of the Class. Class c = e. getClass (); // return class name, including package name c. getName (); // Class. forName () gets the Class object corresponding to the Class name // This method can be executed only when className is a Class name or interface name. Otherwise, a check exception is thrown. Whenever this method is used, an exception processor String className = "java. util. date "; Class c1 = Class. forName (className); // T. class indicates the matching T Class Object class cl1 = Date. class; Class cl2 = int. class; // The Virtual Machine manages a Class Object for each type. Use = to compare two class objects if (e. getClass () = Employee. class )... // newInstance () creates an instance of a class. If the class does not have the default constructor, an exception is thrown. getClass (). newInstance (); // create an Object o = Class Based on the Class name. forName ("java. util. date "). newInstance (); // create the Constructor object with parameters by name. newInstance (...);
5.7.2 capture exceptions
There are two types of exceptions: not checked exceptions and checked exceptions. The checked exception compiler checks whether the processor is provided.
try{ statements that maight throw exceptions}catch(Exception e){ handler action}
5.8 inheritance design skills
1: place public operations and domains in the superclass.
2: Do not use protected domains.
The subclass accesses the super-class domain and destroys the encapsulation.
3: Use inheritance to implement the is-a relationship
For example, employees in the super class include wages, and hourly workers do not include wages, which are charged by time. If you implement hourly work by inheritance, you need to add a hourly wage domain for it, but it will also inherit the wage domain in the employee class. It has different meanings from the actual hourly work and does not conform to the is-a relationship.
4: Do not use inheritance unless all inherited methods make sense.
5: do not change the expected behavior when overwriting the method, or change the connotation of the behavior for no reason.
Do not deviate from the original design idea when overwriting the method in the subclass.
6: Use polymorphism instead of type information
The use of polymorphism should be considered in the following cases. If action1 and action2 share the same concept, define a method for this concept and place it in the superclasses or interfaces of the two classes. Then call x. action (); dynamic binding
if(x is of typ1) action1(x);else if (x is of type2) action2(x);
7: Do not use reflection too much