Java object type conversion and polymorphism, java object conversion Polymorphism
Object type conversion
It can be divided into upward transformation and downward Transformation (forced object transformation ). Upward transformation is the process of transforming sub-objects to parent objects. For example, a cat-type object is converted to an animal-type object. A downward transformation is implemented by force transformation, and a parent object is forcibly converted to a sub-object. This is similar to the conversion of basic data types. byte is automatically converted to int (upward transformation) when needed, and int can be forcibly converted to byte (downward transformation ).
For object transformation,After the transition, the unique members of the sub-object will not be accessible.. It means that when an animal is needed, the cat can be passed as an animal, because the cat inherits automatic things, and the cat has all attributes of the animal. But after the upward transformation, a cat is no longer a cat, but viewed as an animal. Its unique attributes and methods are invisible. In other words, after an upward transition, you can only identify the content in the parent object.
You can use the "reference variable instanceof class name" Method to Determine the reference variableObjectWhether the object belongs to a class, that is, "whether the object is a class", for example, declaring a reference to a Cat Class Object "Cat c ", then, "c instanceof Animal" means "is object c an Animal? "For objects whose instanceof returns true, they can all be converted to class objects, but some may need to be forcibly converted.
Upward transformation can be carried out automatically. This is logical. Dogs inherit from animals and are itself an animal. Therefore, when animals are needed, when a dog is lost, it is automatically transformed into animals. However, a dog is no longer a dog but an animal, so its unique members are no longer visible.
The forced conversion method is the same as the forced conversion of basic data types. The target type is added before the object to be converted. For example, to forcibly convert animal a to dog d:Dog d = (Dog)a.
The following is an example of object type conversion, which makes a good analysis of whether it can be transformed, whether it can access certain members after transformation, and so on.
class Animal { String name; Animal(String name) {this.name = name;}}class Cat extends Animal { String eyecolor; Cat(String name,String color) {super(name); this.eyecolor = color;}}class Dog extends Animal { String furcolor; Dog(String name,String color) {super(name); this.furcolor = color;}}public class OCast { public static void main(String [] args) { Animal a = new Animal("animal"); Cat c = new Cat("cat","blue"); Dog d = new Dog("dog","black"); System.out.println( a instanceof Animal);//return true System.out.println( c instanceof Animal);//return true System.out.println( d instanceof Animal);//return true System.out.println( a instanceof Cat); //return false System.out.println(a.name); //return animal a = new Dog("yellowdog","yellow"); //object Dog upcast to Animal System.out.println(a.name); //return yellowdog System.out.println(a instanceof Animal); //return true System.out.println(a instanceof Dog); //return true //System.out.println(a.furcolor); //error! because a was regarded as Animal Dog d1 = (Dog)a; // because "a instanceof Dog" is true,so force cast Animal a to Dog System.out.println(d1.furcolor); //return yellow }}
Fora = new Dog("yellowdog",yellow)A is of the Animal type, but it points to the Dog object. That is to say, it is a Dog, so it is also an Animal class, soa instanceof Animal);Anda instanceof Dog;All are true, which is determined by its "Pointer. However, because it is of the Animal type, the type determines what data can be stored. It is invisible to existing but non-conforming data, therefore, the Animal type determines that it can only see the Animal part of the Dog object. For example:
Since it can be transformed upwards and combined with the logic judgment of instanceof, it can achieve good scalability. For example, the Animal sing (Animal a) method requires an Animal. You can give it a dog d, at this time, it will be transformed upwards (just like the double type is required but an int data is given). Although the transformation is completed, the actual reference of Dog d is still a Dog object, soif (a instanceof Dog)If the judgment is true, a statement that reflects the particularity of the dog's sing () method is called. If a cat is passed, if statements that reflect the particularity of the cat's sing () method are judged and called. In this way, you only need to add an if statement to add an animal at any time. See the following example:
class Animal { String name; Animal(String name) { this.name = name; }}class Cat extends Animal {Cat(String name) {super(name);}}class Dog extends Animal {Dog(String name) {super(name);}}public class TestCast { public static void main(String [] args) { TestCast t = new TestCast(); Animal a = new Animal("animal"); Animal c = new Cat("cat"); Animal d = new Dog("dog"); t.sing(a);t.sing(c);t.sing(d); } void sing(Animal a) { if ( a instanceof Cat) { Cat cat = (Cat)a; System.out.println("cat is singing"); } else if(a instanceof Dog) { Dog dog = (Dog)a; System.out.println("dog is singing"); } else { System.out.println("not an instance of animal"); } }}
If there is no object transformation, define one sing () in Dog and one sing () in Cat (). To add an animal category, the animal category also needs to define a sing (). Now it is much more convenient. You can directly modify the if statement in the sing () method.
Note that the above sing () method does not belong to Animal or other subclass methods, but is independently defined in other classes for calling.
Polymorphism
Although the upward transformation has improved the scalability to a certain extent, the improvement is not too high. Based on the upward transformation, java polymorphism achieves better scalability and convenience.
Polymorphism is also called dynamic binding or post-binding. It is the binding during execution, not during compilation (this is static binding or pre-binding ).
The principle of polymorphism is: when a method to be rewritten is called after the upward transformation, the parent class method should be called, but the method to be rewritten by the subclass will be dynamically called. In fact, binding during compilation is indeed a parent class method, but it dynamically transfers the corresponding method of the subclass during execution.
For example, the sing () method of the Animal class, Cat and Dog classes both overwrite the sing () method. When an Animal object is required and a Cat class is passed, the Cat's sing () method is called. The dynamic binding logic is similar to the following code:
void sing(Animal a) { if ( a instanceof Cat) { Cat cat = (Cat)a; System.out.println("cat is singing"); } else if(a instanceof Dog) { Dog dog = (Dog)a; System.out.println("dog is singing"); } else { System.out.println("not an instance of animal"); }}
Here is an example of polymorphism:
class Animal { private String name; Animal(String name) {this.name = name;} public void sing(){System.out.println("animal sing...");}}class Cat extends Animal { private String eyeColor; Cat(String n,String c) {super(n); eyeColor = c;} public void sing() {System.out.println("cat sing...");}}class Dog extends Animal { private String furColor; Dog(String n,String c) {super(n); furColor = c;} public void sing() {System.out.println("dog sing...");}}class Lady { private String name; private Animal pet; Lady(String name,Animal pet) {this.name = name; this.pet = pet;} public void myPetSing(){pet.sing();}}public class DuoTai { public static void main(String args[]){ Cat c = new Cat("catname","blue"); Dog d = new Dog("dogname","black"); Lady l1 = new Lady("l1",c); Lady l2 = new Lady("l2",d); l1.myPetSing(); l2.myPetSing(); }}
The compiled execution result is:
cat sing...dog sing...
In the above example, the construction method of the Lady class and the Code for calling the sing () method are:
Lady(String name,Animal pet) {this.name = name; this.pet = pet;}public void myPetSing(){pet.sing();}
If the pet of the Lady object is constructed as Cat Object c, this c will first be transformed to an Animal class, that is to say, although the pet attribute of Lady points to a "Cat c" object, however, it can only see the Animal part of the parent object. SomyPetSing(pet.sing();)The method will naturally call the sing () method of the Animal class. The above process is considered by the compiler and also the process of static binding or pre-binding.
However, after compilation, although the pet attribute can only see the Animal part, pet. sing () is converted to c. sing () during execution (). This is equivalent to a forced conversion of object types.Cat petx = (Cat)pet.This is a process of dynamic binding or later binding, also known as polymorphism.
In fact, after an object is new, all the methods involved are put in a list of methods in the code segment memory area. This list contains sub-classes and parent classes, but sometimes invisible methods cannot be called. When executing a program, the internal mechanism can search for the method that best matches the environment from the method list and execute it.
The key points of technology for implementing polymorphism are:
- (1) define a parent class to reference f and point it to a subclass object, that is, perform upward transformation;
- (2) override the method of the parent class and use the parent class to reference f. In this way, you can program the parent class.
As in the preceding example, pet is defined as an Animal class rather than a specific subclass and pet. sing () is called in the method (). In this way, you do not need to consider whether pet is Cat/Dog. When adding a Bird class to a function extension, you do not need to modify the code of the Lady class.
For example, the parent class Animal, subclass Dog, and method sing ().
Class Animal {public void sing (A);} class Dog extends Animal {public void sing (B);} public class Test {Animal a = new Dog (); // The parent class references variable a pointing to the sub-object Dog, which will be transformed to. sing (); // use the parent class to reference variable a to reference the rewritten method sing (). During execution, the dynamic link will be bound to the Dog's sing ()}
Join the study exchange group 569772982 to learn and exchange.