Basic Java learning notes - Day10 - Chapter 2
System: Win10
JDK: 1.8.0_121
IDE: IntelliJ IDEA 2017.3.7
2.1 general
introduce
Polymorphism is the third feature of object-oriented after encapsulation and inheritance
In life, such as running, kittens, dogs and elephants run differently. Another example is the action of flying, insects, birds and aircraft are also different. It can be seen that the same behavior can present different forms through different things. Polymorphism describes such a state
definition
- Polymorphism: refers to the same behavior with multiple different manifestations
Premise [key]
- Inherit or implement [one of two]
- Rewriting of methods [meaning embodiment: no rewriting, meaningless]
- Parent class reference points to sub class object [format representation]
2.2 expression of polymorphism
Format of polymorphism:
Parent type variable name = new Subclass object; Variable name.Method name();
Parent class type: refers to the parent class type inherited by the child class object or the implemented parent interface type
The code is as follows:
Fu fu = new Zi(); fu.method();
When calling a method using polymorphism, first check whether there is the method in the parent class. If not, there will be a compilation error; If so, the subclass overridden method is executed. The code is as follows:
Define parent class:
public abstract class Animal { public abstract void eat(); }
Define subclasses:
public class Cat extends Animal { @Override public void eat() { System.out.println("Eat fish"); } } public class Dog extends Animal { @Override public void eat() { System.out.println("Eat bones"); } }
Define test class:
public class Test { public static void main(String[] args) { // Polymorphic forms, creating objects Animal a1 = new Cat(); // Cat eat is called a1.eat(); // Polymorphic forms, creating objects Animal a2 = new Dog(); // Dog's eat is called a2.eat(); } }
Operation results:
2.3 benefits of polymorphism
In the actual development process, the parent type is used as the formal parameter of the method, passing the subclass object to the method and calling the method, which can better reflect the expansibility and convenience of polymorphism. The code is as follows:
Define parent class:
public abstract class Animal { public abstract void eat(); }
Define subclasses:
public class Cat extends Animal { @Override public void eat() { System.out.println("Eat fish"); } } public class Dog extends Animal { @Override public void eat() { System.out.println("Eat bones"); } }
Define test class:
public class Test { public static void main(String[] args) { // create object Cat c = new Cat(); Dog d = new Dog(); // Call showCatEat showCatEat(c); // Call showDogEat showDogEat(d); /* The above two methods can be replaced by showAnimalEat(Animal a) method And the implementation effect is consistent */ showAnimalEat(c); showAnimalEat(d); } public static void showCatEat(Cat c) { c.eat(); } public static void showDogEat(Dog d) { d.eat(); } public static void showAnimalEat(Animal a) { a.eat(); } }
Operation results:
Due to the support of polymorphism, the Animal type of showAnimalEat method is the parent type of Cat and Dog. The parent type accepts child objects. Of course, Cat objects and Dog objects can be passed to the method
When the eat method is executed, the polymorphism stipulates that the subclass rewriting method is executed, so the effect is naturally consistent with the showCatEat and showDogEat methods, so showAnimalEat can completely replace the above two methods
It's not just substitution. In terms of expansibility, no matter how many subclasses appear later, we don't need to write showxxeat method. We can use showAnimalEat directly
Therefore, the benefits of polymorphism are reflected in the simplicity of programming and good expansion
2.4 reference type conversion
Polymorphic transformation can be divided into upward transformation and downward transformation
Upward transformation
- Upward Transformation: polymorphism itself is the process of upward transformation from subclass type to parent type, which is the default
When the parent class reference points to a subclass object, it is an upward transformation
Use format:
Parent type variable name = new Subclass type(); For example: Animal a = new Cat();
Downward transformation
- Downward Transformation: the process of downward transformation from parent type to child type. This process is mandatory
For a subclass object that has been transformed upward, the parent class reference can be transformed into a subclass reference. The format of forced type conversion can be used, that is, downward transformation
Use format:
Subclass type variable name = (Subclass type)Parent variable name; For example: Cat c = (Cat)a;
Why transform?
When calling a method in a polymorphic way, first check whether the method exists in the parent class. If not, there will be a compilation error. In other words, you cannot call methods that are owned by a subclass but not by a parent class. Compilation errors, let alone running. This is also a little "trouble" brought by polymorphism. Therefore, if you want to call subclass specific methods, you must make a downward transformation.
Transformation demonstration, the code is as follows:
Define class:
public abstract class Animal { public abstract void eat(); } public class Cat extends Animal { @Override public void eat() { System.out.println("Eat fish"); } public void catchMouse() { System.out.println("Catch a mouse"); } } public class Dog extends Animal { @Override public void eat() { System.out.println("Eat bones"); } public void watchHouse() { System.out.println("Housekeeping"); } }
Define test class:
public class Test { public static void main(String[] args) { // Upward transformation Animal a = new Cat(); a.eat(); //Cat eat is called // Downward transformation Cat c = (Cat)a; c.catchMouse(); // catchMouse of Cat is called } }
Operation results:
Abnormal transformation
In the process of transformation, if you are not careful, you will encounter such problems. Clear the following code:
public class Test { public static void main(String[] args) { // Upward transformation Animal a = new Cat(); a.eat(); //Cat eat is called // Downward transformation Dog d = (Dog)a; d.watchHouse(); // What is called is Dog's watchHouse } }
Operation results:
This code can be compiled, but when running, ClassCastException and type conversion exception are reported! This is because, of course, Cat type objects created explicitly cannot be converted into Dog objects at run time. These two types do not have any inheritance relationship and do not conform to the definition of type conversion.
To avoid the occurrence of ClassCastException, Java provides the instanceof keyword to verify the type of reference variables. The format is as follows:
Variable name instanceof data type If the variable belongs to this data type, return true If the variable does not belong to this data type, return false
Therefore, before conversion, we'd better make a judgment. The code is as follows:
public class Test { public static void main(String[] args) { // Upward transformation Animal a = new Cat(); a.eat(); //Cat eat is called // Downward transformation if (a instanceof Cat) { Cat c = (Cat) a; c.catchMouse(); // catchMouse of Cat is called } else if (a instanceof Dog) { Dog d = (Dog) a; d.watchHouse(); // The call is Dog's watchHouse } } }
Operation results: