06 - object oriented programming (intermediate part II)

Posted by mdemetri2 on Sun, 09 Jan 2022 07:01:50 +0100

1, Method override

Basic introduction

Method override means that a subclass has a method whose name, return type and parameters are the same as those of a method of the parent class. Then we say that this method of the subclass overrides the methods of the parent class.

Use case

public class Animal {
	public void cry() {
		System.out.println("Animal cry..");
	}
}

public class Dog extends Animal{

	//1. Dog is a subclass of Animal
	//2. Dog's cry method has the same definition form as Animal's cry method (name, return type, parameter)
	//3. At this time, we say that Dog's cry method rewrites Animal's cry method
	public void cry() {
		System.out.println("The dog barked..");
	}
}

matters needing attention

1)The method name and parameter list of the method of the subclass should be exactly the same as the method name and parameter list of the parent method.

2)The return type of the subclass method is the same as that of the parent method, or it is a subclass of the parent return type
	For example, the return type of the parent class is Object,The subclass return type is String
	Public Object getInfo() { }
	public String getInfo() { }

3)Subclass methods cannot reduce the access rights of parent methods
	public > protected > default > private

The difference between override and overload

name Occurrence range Method name parameter list Return type Modifier
overload This category Must be the same There is at least one difference in type, number, or order No requirement No requirement
override Parent child class Must be the same identical Subclass methods cannot narrow the access scope of parent methods

2, Object oriented programming - polymorphism

Basic introduction

Methods or objects have multiple forms. Polymorphism is the third feature of object-oriented. Polymorphism is based on encapsulation and inheritance.

Concrete embodiment of polymorphism

1)Polymorphism of methods
public class PloyMethod {
	public static void main(String[] args) {
	
		//Method overloading reflects polymorphism
		A a = new A();
		//Here, if we pass in different parameters, we will call different sum methods, which reflects polymorphism
		System.out.println(a.sum(10, 20));
		System.out.println(a.sum(10, 20, 30));

		//Method rewriting reflects polymorphism
		B b = new B();
		a.say();
		b.say();
	}
}

class B { //Parent class
	public void say() {
		System.out.println("B say() Method called...");
	}
}

class A extends B {//Subclass
	public int sum(int n1, int n2){
		//And the following sum constitute an overload
		return n1 + n2;
	}
	
	public int sum(int n1, int n2, int n3){
		return n1 + n2 + n3;
	}
	
	public void say() {
		System.out.println("Asay() Method called...");
	} 
}

//Conclusion: Rewriting and overloading reflect polymorphism
2)Polymorphism of objects
	1 - The compile type and run type of an object can be inconsistent
	2 - The compilation type is determined when defining the object and cannot be changed
	3 - The operation type can be changed
	4 - When compiling type definitions =To the left of the number, look at the operation type =To the right of the number
	For example:
	Animal animal = new Dog();
	//The compilation type of animal is animal and the running type is Dog
	animal = new Cat();
	//The running type of animal becomes Cat, and the compiled type is still animal

Supplement: compile type and run type
	For example: Person person = new Student();
	This line of code will generate a person Variable whose compile time type is Person,The runtime type is Student
	
	When a class inherits, the child class overrides the same properties as the parent class
	
	To sum up, the object access variable depends on the declaration, and the access method depends on the actual object type( new (type of output)
	
	java It is allowed to assign a subclass object directly to a parent class reference variable without any type conversion
	Or called upward transformation, which is automatically completed by the system
//Example: feeding method in a master human master

Public void feed(Dog dog, Bone bone) {
	System.out.println(this.name + ""Here" + dog.getName() + "eat" + bone.getName());
}
Public void feed(Cat cat, Fish fish) {
	System.out.println(this.name + ""Here" + cat.getName() + "eat" + fish.getName());
}

//In order to improve code reusability and reduce the amount of redundant code, the following methods can be used instead:

Public void feed(Animal animal, Food food) {
	System.out.println(this.name + ""Here" + animal.getName() + "eat" + food.getName());
}

//Using the principle of polymorphism:
//The compilation type of the animal variable is animal, which can point to (receive) the object of the animal subclass
//The compiled type of the food variable is food, which can point to (receive) the object of the food subclass

Polymorphic considerations

The premise of polymorphism is that there is an inheritance relationship between two objects (classes)

  • Polymorphic upward transformation

      	1)Essence: the reference of the parent class points to the object of the child class
      	2)Syntax:
      		Parent type reference name = new Subclass type();
      	3)Features: see the left for compilation type and the right for operation type.
    
//Upward Transformation: the reference of the parent class points to the object of the child class
//Syntax: parent type reference name = new subclass type ();
Animal animal = new Cat();
Object obj = new Cat();// Object is also a parent class of Cat


//The rules for upward transformation of calling methods are as follows:

//(1) All members in the parent class can be called (subject to access rights)
//(2) However, you cannot call a specific member of a subclass
//(3) Because in the compilation stage, which members can be called depends on the compilation type / / animal catchMouse(); error
//(4) the final operation effect looks at the specific implementation of subclass (operation type), that is, when the method is invoked, it starts looking up the method / / from the sub class (running type) and then calls it, and the rule is consistent with the method call rule before.

  • Polymorphic downward transformation

      	1)Syntax:
      		Subclass type reference name = (Subclass (type) parent class reference;
      	2)Only references of the parent class can be coerced, and objects of the parent class cannot be coerced
      	3)It is required that the reference of the parent class must point to an object of the current target type
      	4)After the downward transformation, all members in the subclass type can be called
    
//Polymorphic downward transformation
//(1) Syntax: subclass type reference name = (subclass type) parent class reference; 
//(2) It is required that the reference of the parent class must point to an object of the current target type
//Cat is compiled as cat and run as cat 
Animal animal1 = new Cat();
Cat cat = (Cat) animal1;

//The compilation type of Dog is Dog, and the running type is Dog
Animal animal2 = new Dog();
Dog dog = (Dog) animal2;
  • Supplement:

      	Property is not rewritten! The value of the attribute depends on the compilation type
    
      	instanceOf The comparison operator is used to judge whether the operation type of the object is XX Type or XX Subtype of type
    
class AA {} //Parent class
class BB extends AA {}//Subclass

BB bb = new BB();
System.out.println(bb instanceof BB);// true 
System.out.println(bb instanceof AA);// true 

//Aacompile type AA, run type BB 
//BB is subclass AA 
AA aa = new BB();
System.out.println(aa instanceof AA); // true
System.out.println(aa instanceof BB); // true

Object obj = new Object(); 
System.out.println(obj instanceof AA);//false 
String str = "hello"; 
//System.out.println(str instanceof AA); 
System.out.println(str instanceof Object);//true

Dynamic binding mechanism of Java

1)When an object method is called, the method is associated with the running type of the object / Memory address binding.
2)There is no dynamic binding mechanism for calling object properties. Where to declare and where to use properties.

Application of polymorphism

  1. Polymorphic array
    The definition type of the array is the parent type, and the actual element type saved in it is the subclass type
// Application example: an existing inheritance structure is as follows: it is required to create a Person object
// Let both Student and Teacher inherit Person.
// Two Student objects and two Teacher objects are uniformly placed in the array, and the say method of each object is called
Person[] persons = new Person[5];
persons[0] = new Person("jack", 20);
persons[1] = new Student("mary", 18, 100);
persons[2] = new Student("smith", 19, 30.1);
persons[3] = new Teacher("scott", 30, 20000);
persons[4] = new Teacher("king", 50, 25000);
  1. Polymorphic parameters
    The formal parameter type defined by the method is the parent type, and the argument is allowed to be the child type. (later, we use interface programming, which is generally subclass type)

3, Detailed explanation of Object class

1. equals method

equals method

== and equals Comparison of
	== Is a comparison operator
		1)You can judge both the basic type and the reference type
		2)If the basic type is judged, the judgment is whether the values are equal
		Example:
		int i = 10; double d = 10.0;
		3)If you judge the reference type, you judge whether the addresses are equal
		That is, judge whether it is the same object
	
	equals yes Object Methods in classes
		1)equals Only reference types can be judged
		2)The default judgment is whether the addresses are equal. This method is often overridden in subclasses
		Used to judge whether the contents are equal
		such as Integer,String

String class rewrites the source code of equals method

/*
	//Look at the source code of Jdk, the equals method of String class
	//The equals method of Object is rewritten to compare whether the two string values are the same
*/
public boolean equals(Object anObject) {
	if (this == anObject) {		//If it is the same object
		return true;//Return true
	}
	
	if (anObject instanceof String) {	//Judgment type
		String anotherString = (String)anObject;	//Downward transformation
		int n = value.length;
		if (n == anotherString.value.length) {	//If the length is the same
			char v1[] = value;
			char v2[] = anotherString.value;
			int i = 0;
			while (n-- != 0) {	//Then compare the characters one by one
				if (v1[i] != v2[i])
					return false;
				i++;
			}
			return true;	//Returns true if all characters of two strings are equal
		}
	}
	return false;	//If the comparison is not a string, false is returned directly
}

Object class equals method source code

//That is, the equals method of the Object class defaults to comparing whether the Object addresses are the same
//That is to judge whether two objects are the same object
public boolean equals(Object obj) {
	return (this == obj);
}

Integer class rewrites the source code of equals method

//From the source code, we can see that the Integer class also overrides the equals method of the Object class
//It becomes to judge whether the two values are the same
public boolean equals(Object obj) {
	if (obj instanceof Integer) {
		return value == ((Integer)obj).intValue();
	}
	return false;
}

Try rewriting equals yourself
If we have a Person object with name, age and gender attributes, and only need these three values to be the same, then we think this object is equal.

//Override the equals method of Object 
public boolean equals(Object obj) {
	//Judge whether the two objects compared are the same object, and return true directly 
	if(this == obj) {
		return true; 
	}
	
	//Type judgment
	if(obj instanceof Person) {//It's Person. We compare
	//Make a downward transformation because I need to get the properties of obj
		Person p = (Person)obj;
		return this.name.equals(p.name) && this.age == p.age && this.gender == p.gender;
	}
	//If it is not Person, false is returned directly 
	return false;
}

2. hashCode method

Basic introduction

1)Improve the efficiency of containers with hash structure.
2)If two references point to the same object, the hash value must be the same.
3)If two references point to different objects, the hash value is different.
4)The hash value is mainly based on the address number!,However, the hash value cannot be completely equivalent to an address.
5)Later in the collection, if necessary hashCode It will also be rewritten.
public class HashCode_ {
	public static void main(String[] args) {
		AA aa = new AA();
		AA aa2 = new AA();
		AA aa3 = aa;
		
		System.out.println("aa.hashCode()=" + aa.hashCode());
		System.out.println("aa2.hashCode()=" + aa2.hashCode());
		System.out.println("aa3.hashCode()=" + aa3.hashCode());
	} 
}
class AA {}

3. toString method

Basic introduction

1)Default return: full class name+@+Hex of hash value
[see Object of toString [method]
2)Subclasses often override toString Method to return the property information of the object.
3)rewrite toString Method, when printing an object or splicing an object, it will automatically call the toString Form.
4)When outputting an object directly, toString Method is called by default.
such as System.out.println(monster); Will be called by default monster.toString()

toString() source code of Object

//(1)getClass(). Full class name of getname () class (package name + class name)
//(2)Integer.toHexString(hashCode()) converts the hashCode value of an object to a hexadecimal string
public String toString() {
	return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

4. finalize method

Basic introduction

When an object is recycled, the system automatically calls the finalize method of the object. Subclasses can override this method to release resources.
When to recycle: when an object has no reference, the jvm considers the object as a garbage object, and will use the garbage collection mechanism to destroy the object. Before destroying the object, it will call the finalize method.
The call of garbage collection mechanism is determined by the system (that is, it has its own GC algorithm) or through system GC () actively triggers the garbage collection mechanism.

//Override finalize
@Override
protected void finalize() throws Throwable {
	System.out.println("We destroy cars" + name);
	System.out.println("Some resources were released...");
}

Note: this blog quotes Mr. Han Shunping's Java course