V. Inheritance
- Inheritance Definition: Constructing New Classes Based on Existing Classes
- Reflection Definition: The ability to discover more classes and attributes while the program is running
- Polymorphic Definition: An object variable can indicate many actual types of phenomena
- Dynamic Binding Definition: The phenomenon of automatically choosing to call methods at runtime
5.1 Categories, Superclasses and Subclasses
5.1.2 Covering Method
-
rule
- The method signature in the superclass is the same as that in the subclass (method name and parameter list), and the return value type needs to be guaranteed to be the same or a subclass of the return value type (covariant return type)
-
The difference between coverage and overload
- Overlay is the same method signature
- Overload is the same method name, parameter list must be different, there is no restriction on return type, access modifier, exception declaration <! - can be seen as a new method, but the method name is special - >.
5.1.6 Method Call Process
- graphic
5.1.7 Prevent Inheritance: final classes and methods
-
rule
- Classes can not be inherited after being modified with final, and methods in them are automatically modified with final. Domain does not include
- After the method is modified with final, the subclass cannot override the current method.
5.1.8 Mandatory Type Conversion
-
Be careful
- Before forcing type conversion, use the instanceof method to determine whether the type belongs to
5.2 Object: Superclass of all classes
- Note: Only basic types are not objects
5.2.1 equals
-
Characteristic
- Reflexivity: x is any non-null reference, and x.equals(x) should return true
- Symmetry: For any reference x, y, if and only if x.equals(y) returns true, then y.equals(x) returns true as well.
- Transitivity: For any reference x, y, z, if x.equals(y) returns true and y.equals(z) returns true, then x.equals(z) returns true as well.
- Consistency: If the object referenced by x and Y does not change, x.equals(y) should always return true
-
The Difference between equals and Equivalents - Emphasis
-
Equal sign (==)
- Basic data types (also known as raw data types): byte,short,char,int,long,float,double,boolean. The comparison between them, using the double sign (==), compares their values.
- Reference data types: When they compare with (==), they compare their storage address in memory (heap memory address, to be exact).
-
equals
- The initial default behavior of the method is to compare the memory address value of the object
- In some class libraries, this method has been rewritten, such as String, Integer, Date, to compare whether the member variables of objects have the same values.
-
-
Reasonable equals rewrite logic
- The display parameter is declared Object <! -- Overrides the equals method - >.
- Judging whether to refer to the same object <!--Compared with the judgment domain, the current judgment cost is low - > The current judgment cost is lower than that of the judgment domain.
- Judge whether it is empty
- Determine whether it belongs to the same class <! -- Use getClass() and instanceof - >.
- Converting the comparison object to the corresponding type of variable
- Domain comparison <! -- Use == to compare basic type domains, and use equals to compare object domains - >.
5.2.3 hashCode method
- hash code definition: is an integer value derived from an object <! - objects only, so the basic data type needs to be converted to a wrapper class - >.
-
Be careful
-
The same hashCode exists for objects created by wrapper classes of strings and basic data types because they are derived from content
<! - Realization - >
public class TestHashCode { public static void main(String[] args) { String s1 = "a"; String s2 = "a"; Integer i = 10; Integer k = 10; System.out.println(s1.hashCode()); System.out.println(s2.hashCode()); System.out.println(s1.equals(s2)); System.out.println(i.hashCode()); System.out.println(k.hashCode()); System.out.println(i.equals(k)); } }/* output 97 97 true 10 10 true */
- If the equals method is redefined, the hashCode method must be redefined so that users can insert objects into the hash table. If redefined, equals will be equal and hashCode will be different
<! - Equals and hashCode must be defined in the same way. If two objects equals are true, they must have the same hashCode. The opposite is not true. >
<! - If the defined equals compare employee IDs, hashCode needs to hash IDs instead of employee names or addresses - > the
-
5.2.4 toString method
- Purpose: Returns a string representing the value of an object
-
Be careful
-
The common reason for toString methods is that when an object is connected to a string via operator + connection, the compiler will automatically use the toString method
<! - Realization - >
public class TestToString { String name = "asd"; public static void main(String[] args) { TestToString testToString = new TestToString(); System.out.println(testToString+"jkl"); } }/* output Five.TestToString.TestToString@1218025cjkl */
-
It is recommended that the toString method be rewritten, and the method invoked by default is less readable.
<! - Realization - >
public class TestToString { String name = "asd"; @Override public String toString() { return "TestToString{" + "name='" + name + '\'' + '}'; } public static void main(String[] args) { TestToString testToString = new TestToString(); System.out.println(testToString+"jkl"); } }/* output TestToString{name='asd'}jkl */
-
5.2.5 getClass method
-
Purpose: Return class objects containing object information
<! - Realization - >
public class TestToString { String name = "asd"; public static void main(String[] args) { TestToString testToString = new TestToString(); System.out.println(testToString.getClass()); } }/* output class Five.TestToString.TestToString */
5.3 Generic Array List
- Generic Definition: Java generic parameters can only represent classes, not individual objects
1.ArrayList
-
Definition: Generic classes with type parameters
<! - Realization - >
// Usage method ArrayList<Employee> staff = new ArrayList<Employee>(); // The generic type is Employee
-
rule
- Use add method to add new data. If space is exhausted, larger arrays are automatically created and original data copied into larger arrays
- Using the size method to get the actual number of elements
- Use trimToSize to clear excess storage space
- Accessing and setting elements using get and set methods
-
Be careful
- The core difference between array lists and array sizes is that the space allocated by an array of 100 is already in memory; array lists have the potential to store only 100, even after initialization.
- When used, specify the type of generic type. Because no generic type is specified, storing and modifying data accepts objects of any type because Object is used
5.4 Object Packer and Automatic Packing
1. Automatic packing
-
Packaging Definition: Basic Data Type Converted to Basic Type Packaging Class
<! - Realization - >
// Boxing public class TestAutoBoxing { public static void main(String[] args) { ArrayList<Integer> list = new ArrayList<Integer>(); list.add(5); // Equivalent to list.add(Integer.valueOf(5)); } }/* conclusion 1.list The element in the 2.When added using the. add() method, the type added is the basic type int 3.So automatically convert to list.add(Integer.valueOf(5)) */
-
Be careful
-
Automatic packing specification requires boolean, byte, char less than or equal to 127, short s and ints between - 128 and 127 to be packaged into fixed objects.
The reason is: IntegerCache.low defaults to - 128; IntegerCache.high defaults to 127, beyond the scope will create object storage, otherwise return the value directly. Reduce new and jvm pressure.
<! - Realization - >
public class TestAutoBoxing { public static void main(String[] args) { // Use packaging classes Integer a = 127; Integer b = 127; Integer c = 128; Integer d = 128; System.out.println("a == b:"+(a == b)); System.out.println("c == d:"+(c == d)); } }/* output a == b:true c == d:false */
- Because the wrapper class reference can be null, NullPointerException will occur
- If Integer and Double are used together, Integer will unpackage, upgrade to double, and then pack to Double.
- Auto-unpacking and auto-packing are recognized by compilers, not virtual machines.
-
2. Auto-disassembly
-
Unpacking Definition: Breaking Packaging Class Data into Basic Type Data
<! - Realization - >
public class TestAutoBoxing { public static void main(String[] args) { // Boxing ArrayList<Integer> list = new ArrayList<Integer>(); list.add(5); // Unpacking int intType = list.get(0); // Is equal to int intType = list. get (0). int Value (); } }/* conclusion 1.list The element in the 2.When obtained using the. get() method, the value type obtained is Integer 3.So the automatic transformation is int intType = list.get(0).intValue(); */
5.5 Method of Variable Parameters
- Variable Definition of Parameters: A Method for Supporting Calls with Variable Number of Parameters
-
format
// Use... Double ... args
<! - For example, the System.out.printf() method can receive mu lt iple parameters - >.
// Receiving multiple parameters at the same time System.out.printf("%d %s",n,"name"); // The underlying implementation code public PrintStream printf(String format, Object ... args) { return format(format, args); } /* conclusion 1."String format"For format strings, "Object... args" is an array of Object objects, so the number is variable */
<! - Find the maximum value with variable parameters - >
public class TestFindMax { static void findMax(Object ... args){ double largest = Double.NEGATIVE_INFINITY; for (Object y: args ) { Double z = (Double) y; if (z > largest) largest = z; } System.out.println(largest); } public static void main(String[] args) { TestFindMax.findMax(3.454,34.3); } }
5.6 Enumeration Classes
-
format
enum EnumName{ MAX,MIN,DEDIUM; }
-
Be careful
-
Enumeration classes are instances, so you can create variables in instances, but you must use constructors to assign values
<! - Realization - >
public class TestEnum { public enum Size{ MAX("max",3),MIN("min",1),MEDIUM("medium",2); // Membership variables private String name; private int num; // Method of Constructing Membership Variables Size(String name , int i) { this.name = name; this.num = i; } } public static void main(String[] args) { // In the same class, you can access the private member variable name String name = Size.MAX.name; System.out.println(name); } }
-
5.7 Reflections - Key Points
- Reflection Definition: Programs that support the ability to analyze classes
- Reflection mechanism: encapsulating parts of a class into other objects
Schematic diagram
-
Three Ways to Get Class Objects
- Class.forName("full class name"): In the first stage, the bytecode file is loaded into memory and the Class object is retrieved.
Used mostly for configuration files
- Class Name. Class: In the second stage, through the class attribute of the class name
Used mostly for parameter transfer
-
Object. getClass(): In the third stage, get it through Object's getClass method
Byte code acquisition for objects
<! - Realization - >
public class TestReflectionClass { public static void main(String[] args) throws Exception { /* Class Three Ways of Object Acquisition 1.Get it through Class.forclass("full class name") 2.Get by class name. class() 3.By object. getClass() method */ // 1. Get it through Class.forclass("full class name") Class cls1 = Class.forName("Five.TestReflection.Person"); System.out.println(cls1); // 2. Get by class name. class() Class cls2 = Person.class; System.out.println(cls2); // 3. By Object. getClass() Method Person p = new Person(); Class cls3 = p.getClass(); System.out.println(cls3); // 4. Compare three class references to the same Class object System.out.println("Compare three class Does the reference refer to the same thing? Class object"); System.out.println("cls1 == cls2:"+(cls1 == cls2)); System.out.println("cls1 == cls2:"+(cls1 == cls3)); } }/* output class Five.TestReflection.Person class Five.TestReflection.Person class Five.TestReflection.Person Compare three class references to the same Class object cls1 == cls2:true cls1 == cls2:true */
- Class.forName("full class name"): In the first stage, the bytecode file is loaded into memory and the Class object is retrieved.
-
Be careful
- The same bytecode file (. class) is loaded only once in a program run, so the three ways to get the Class object are the same.
-
purpose
- The ability to analyze classes at runtime
- Operating objects at runtime
<! - Examples --> ____________
<! - In the running process, the following methods belong to the contents of the methods object in the Class class object - >.
- Implementing General Array Operating Code
- Using Mehtod objects, similar to function pointers in C++.
5.7.1 Class class
1. Functions in Class Objects
1.1 Get member variable values
<! -- You can imagine that Class is a special class, where Field is a member attribute. There are more specific member attributes in this member attribute, and field is a member attribute that can get and set values through get and set methods - >.
-
rule
- Field[] getFields(): Gets all public modified member variables (including superclasses)
- Field getField(): Gets the specified public modified member variables (including superclasses)
- Field [] getDeclared Fields (): Gets all member variables (even private ly modified, violent reflexes)
- Field getDeclaredField(): Gets the specified member variables (even private modifiers, violent reflexes)
-
Be careful
-
When getFields and getDeclaredFields() are obtained, getFields can simultaneously obtain public variables in superclasses and subclasses, and getDeclaredFields() can only obtain variables of all access modifier types in subclasses.
<! - Realization - >
// Superclass public class Father { // Membership variables private String priFatherName; private int priFatherAge; public String pubFatherName; public int pubFatherAge; } // Subclass public class Son extends Father { // Membership variables private String priSonName; private int priSonAge; public String pubSonName; public int pubSonAge; }
// Test class package Five.TestReflection; import java.lang.reflect.Field; public class TestField { public static void main(String[] args) throws Exception { /* getField And getDeclared Field */ // getField System.out.println("--test getField"); Field[] field1 = Son.class.getFields(); for (Field f : field1) { System.out.println(f); } // getDeclaredField System.out.println("--test getDeclaredField"); Field[] field2 = Son.class.getDeclaredFields(); for (Field f : field2) { System.out.println(f); }}} /* output --Testing getField public java.lang.String Five.TestReflection.Son.pubSonName public int Five.TestReflection.Son.pubSonAge public java.lang.String Five.TestReflection.Father.pubFatherName public int Five.TestReflection.Father.pubFatherAge --Test getDeclared Field private java.lang.String Five.TestReflection.Son.priSonName private int Five.TestReflection.Son.priSonAge public java.lang.String Five.TestReflection.Son.pubSonName public int Five.TestReflection.Son.pubSonAge */
-
-
Field Object Method
- get(Object Obj: The Field returned represents the value of the Field on the specified object
- set(Object obj, Object Value: Setting the new value specified by the parameter on the Field object represented by the domain
-
setAccessible(): Ignoring security checks for access modifiers, also known as violent reflex (if you need get or set to use private ly modified variables, you need to use this method) for debugging, persistent storage, and similar mechanisms.
<! - Realization - >
// Superclass public class Father { // Membership variables private String priFatherName; private int priFatherAge; public String pubFatherName; public int pubFatherAge; } // Subclass public class Son extends Father { // Membership variables private String priSonName; private int priSonAge; public String pubSonName; public int pubSonAge; }
// Test class package Five.TestReflection; import java.lang.reflect.Field; public class TestField { public static void main(String[] args) throws Exception { /* get And set method */ Son son = new Son(); // get,public System.out.println("--test get Method getField,Act on public Modifying objects"); Field field3 = Son.class.getField("pubSonName"); Object value3 = field3.get(son); System.out.println(value3); // get,private System.out.println("--test get Method getField,Act on private Modifying objects"); // Because getField only works on public-modified members, it cannot be accessed // Field field4 = Son.class.getField("priSonName"); // field4.setAccessible(true); // Object value4 = field4.get(son); // System.out.println(value4); System.out.println("fail"); // get,private System.out.println("--test get Method getDeclaredField,Act on private Modifying objects"); Field field5 = Son.class.getDeclaredField("priSonName"); // Need to ignore access security checks before acquisition field5.setAccessible(true); Object value5 = field5.get(son); System.out.println(value5); // set,public System.out.println("--test set Method getField,Act on public Modifying objects"); Field field6 = Son.class.getField("pubSonName"); field6.set(son, "Toyz"); Object value6 = field6.get(son); System.out.println(value6); // set,private System.out.println("--test set Method getDeclaredField,Act on private Modifying objects"); Field field7 = Son.class.getDeclaredField("priSonName"); // Need to ignore access security checks before acquisition field7.setAccessible(true); Object value7 = field7.get(son); System.out.println("Before modification, priSonName:"+value7); field7.set(son, "QQ"); value7 = field7.get(son); System.out.println("Before modification, priSonName:"+value7); } } /* output --Testing the get method, using getField, acts on the public modifier object null --Test the get method, using getField, to act on private ly modified objects fail --Test the get method, using getDeclared Field, to act on private ly modified objects null --Test the set method, using getField, to modify the object with public Toyz --Test the set method, using getDeclared Field, to act on private ly modified objects priSonName:null before modification priSonName:QQ before modification */
1.2 Acquisition Construction Method
-
rule
- getConstructor(class <?>... parameterTypes: Get the specified construction method of public modification (excluding superclasses)
- getConstructors(): Gets all constructions of the public modifier (excluding superclasses)
- getDeclaredConstructor(class <?>... parameterTypes: Gets the specified constructor (including private modifiers, violent reflexes, no superclasses)
-
GetDeclared Constructors (): Get all constructions (including private modifiers, violent reflexes, no superclasses)
Get the constructor, you can't get the superclass, because the constructor can't be inherited, so you can't get it.
<! - Realization - >
// Superclass public class Father { public Father(String priFatherName , int priFatherAge , String pubFatherName , int pubFatherAge) { this.priFatherName = priFatherName; this.priFatherAge = priFatherAge; this.pubFatherName = pubFatherName; this.pubFatherAge = pubFatherAge; } public Father() { } private Father(String priFatherName , int priFatherAge){ this.priFatherName = priFatherName; this.priFatherAge = priFatherAge; } } // Subclass public class Son extends Father { public Son(String priSonName , int priSonAge , String pubSonName , int pubSonAge) { this.priSonName = priSonName; this.priSonAge = priSonAge; this.pubSonName = pubSonName; this.pubSonAge = pubSonAge; } public Son(){} private Son(String priSonName , int priSonAge){ this.priSonName = priSonName; this.priSonAge = priSonAge; } }
// Test class public class TestConstructor { public static void main(String[] args) throws Exception { /* getConstructor And getDeclared Constructor */ // getConstructor, parametric constructor and parametric constructor System.out.println("--test getConstructor"); Constructor constructor1 = Son.class.getConstructor(); System.out.println("Parametric constructor:"+constructor1); Constructor constructor2 = Son.class.getConstructor(String.class,int.class,String.class,int.class); System.out.println("Parametric constructor:"+constructor2); // getConstructors System.out.println("--test getConstructors"); Constructor[] constructors3 = Son.class.getConstructors(); for (Constructor c : constructors3) { System.out.println(c); } // getDeclaredConstructor System.out.println("--test getDeclaredConstructor"); Constructor constructor4 = Son.class.getDeclaredConstructor(String.class,int.class); System.out.println(constructor4); // getDeclaredConstructors System.out.println("--test getDeclaredConstructors"); Constructor[] constructor5 = Son.class.getDeclaredConstructors(); for (Constructor c : constructor5){ System.out.println(c); } } } /* output --Test getConstructor Parametric-free constructor: public Five.TestReflection.Son() Parametric constructor: public Five.TestReflection.Son(java.lang.String,int,java.lang.String,int) --Testing getConstructors public Five.TestReflection.Son() public Five.TestReflection.Son(java.lang.String,int,java.lang.String,int) --Test getDeclared Constructor private Five.TestReflection.Son(java.lang.String,int) --Test getDeclared Constructors private Five.TestReflection.Son(java.lang.String,int) public Five.TestReflection.Son() public Five.TestReflection.Son(java.lang.String,int,java.lang.String,int) */
-
Constructor Object Method
-
newInstance(Object Initargs: A new instance constructor of a declarative class of constructors created and initialized using the Constructor object, with specified initialization parameters.
<! - Realization - >
// Test class public class TestConstructor { public static void main(String[] args) throws Exception { /* newInstance(Object... initargs) */ // New Instance (Object... initargs) parametric constructor System.out.println("--newInstance(Object... initargs) Parametric constructor"); Constructor constructor6 = Son.class.getConstructor(); System.out.println(constructor6.newInstance()); // New Instance (Object... initargs) parametric constructor System.out.println("--newInstance(Object... initargs) Parametric constructor"); Constructor constructor7 = Son.class.getDeclaredConstructor(String.class,int.class); constructor7.setAccessible(true); // Ignore access security checks System.out.println(constructor7.newInstance("Toyz",44)); } } /* output --newInstance(Object... initargs) Parametric constructor Son{priSonName='null', priSonAge=0, pubSonName='null', pubSonAge=0} --newInstance(Object... initargs) Parametric constructor Son{priSonName='Toyz', priSonAge=44, pubSonName='null', pubSonAge=0} */
-
1.3 Acquisition Method
-
rule
- getMethod(String name, class <?>... parameterTypes: A specified method for obtaining public modifications (including superclasses)
- getMethods(): A specified method for obtaining public modifications (including superclasses)
- getDeclaredMethod(String name, class <?>... parameterTypes: Gets the specified method (including private modifiers, violent reflexes, no superclasses)
-
GetDeclared Methods (): Get all methods (including private modifiers, violent reflexes, no superclasses)
<! - Realization - >
// Superclass public class Father { // Method public void eat(){ System.out.println("father eat..."); } public void eat(String food){ System.out.println("father eat..."+food); } public void edu(){ System.out.println("father edu..."); }; private void run(){ System.out.println("father run..."); } } // Subclass public class Son extends Father { // Method public void eat(){ System.out.println("son eat..."); } public void eat(String food){ System.out.println("son eat..."+food); } private void run(){ System.out.println("son run..."); } }
// Test class public class TestMethod { public static void main(String[] args) throws Exception { /* getMethod And getDeclared Method */ Son son = new Son(); // getMethod, empty parameter method System.out.println("--test getMethod,Empty parameter method"); Method method1 = Son.class.getMethod("eat"); System.out.println(method1); // getMethods, all methods System.out.println("--test getMethods"); Method[] method2 = Son.class.getMethods(); for (Method m : method2) { System.out.println(m); } // GetDeclared Methods, all methods System.out.println("--test getDeclaredMethods"); Method[] method3 = Son.class.getDeclaredMethods(); for (Method m : method3) { System.out.println(m); }}} /* output --Test getMethod, empty parameter method public void Five.TestReflection.Son.eat() --Test getMethods public java.lang.String Five.TestReflection.Son.toString() public void Five.TestReflection.Son.eat(java.lang.String) public void Five.TestReflection.Son.eat() public void Five.TestReflection.Father.edu() public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException public final void java.lang.Object.wait() throws java.lang.InterruptedException public boolean java.lang.Object.equals(java.lang.Object) public native int java.lang.Object.hashCode() public final native java.lang.Class java.lang.Object.getClass() public final native void java.lang.Object.notify() public final native void java.lang.Object.notifyAll() --Test getDeclared Methods private void Five.TestReflection.Son.run() public java.lang.String Five.TestReflection.Son.toString() public void Five.TestReflection.Son.eat(java.lang.String) public void Five.TestReflection.Son.eat() */
-
Method Object Method
-
invoke(Object obj, Object ... args: The first parameter is implicit and the static method is null. Call the underlying method, which represents the object and specifies parameters for the specified object. A method that can call a superclass
<! - Realization - >
// Test class public class TestMethod { public static void main(String[] args) throws Exception { /* invoke */ // invoke, public method with parameter subclass System.out.println("--test invoke,Parametric subclasses public Method"); Method method4 = Son.class.getMethod("eat",String.class); method4.invoke(son, "Fish"); // invoke, public method with reference parent class System.out.println("--test invoke,Parent class with reference public Method"); Method method5 = Son.class.getMethod("edu"); method5.invoke(son); // invoke, private method without parameter subclass System.out.println("--test invoke,Nonparametric subclasses private Method"); Method method6 = Son.class.getDeclaredMethod("run"); method6.setAccessible(true); method6.invoke(son); } } /* output --Test invoke, public method with parameter subclass son eat...Fish --Testing invoke with reference parent public method father edu... --Test invoke, private ly method without parameter subclass son run... */
-
2.Practice (Reflection)
- Requirements: Write a "framework" to create objects of any class and execute any method through configuration file without changing the code.
-
step
- Write the classes that will be created and the methods that will be executed in the configuration file
- Read configuration files in programs
- Loading classes into memory using reflection
- create object
- Execution method
-
Realization
-
Create classes (demonstration classes needed for configuration files)
package Five.TestReflection; public class Father { public Father() { } // Method public void eat(){ System.out.println("father eat..."); } }
-
create profile
className=Five.TestReflection.Father methodName=eat
-
Read and execute
package Five.TestReflection; import java.io.InputStream; import java.lang.reflect.Method; import java.util.Properties; public class TestReflection { public static void main(String[] args) throws Exception { // 1. Loading configuration files // 1.1 Create pro objects Properties properties = new Properties(); // 1.2 Load configuration files and convert them to collections // 1.2.1 Get the Profile Path ClassLoader classLoader = TestReflection.class.getClassLoader(); InputStream is = classLoader.getResourceAsStream("pro.properties"); properties.load(is); // 2. Get the data defined in the configuration file String className = properties.getProperty("className"); String methodName = properties.getProperty("methodName"); // 3. Loading classes into memory Class cls1 = Class.forName(className); // 4. Creating Objects - Reflections Object object = cls1.newInstance(); // 5. Execution Method - Reflection Method method1 = cls1.getMethod(methodName); method1.invoke(object); } } /* output father eat... */
-