Re-understanding Java (v)----Object-oriented polymorphism (upward transformation and downward transformation)

Source: Internet
Author: User

Polymorphic, probably everyone knows. However, a few people really understand what is polymorphic, polymorphic what are the details? If you see the name of this article, there is no clear concept of polymorphism in your mind, you may wish to come in and see if there is a harvest.

What is polymorphic a simple understanding of polymorphism

Polymorphism, in short, is the ability of the same behavior to have many different manifestations or forms. For example, there is a glass of water, I do not know whether it is warm, ice or hot, but I touch I will know. I touch the Water Cup this action, for different temperatures of water, you will get different results. This is polymorphism.

So, how does it manifest polymorphism in Java? Let's look directly at the code:

 Public  class water {     Public void Showtem() {System.out.println ("My temperature is: 0 degrees."); }} Public  class icewater extends water {     Public void Showtem() {System.out.println ("My temperature is: 0 degrees."); }} Public  class warmwater extends water {     Public void Showtem() {System.out.println ("My temperature is: 40 degrees."); }} Public  class hotwater extends water {     Public void Showtem() {System.out.println ("My temperature is: 100 degrees."); }} Public  class testwater{     Public Static void Main(string[] args) {Water W =NewWarmwater ();        W.showtem (); W =NewIcewater ();        W.showtem (); W =NewHotwater ();    W.showtem (); }}//Results://My temperature is: 40 degrees//My temperature is: 0 degrees//My temperature is: 100 degrees

Here's the way Showtem () is the equivalent of you going to touch the water Cup. The reference variable w of the water type we define is the equivalent of a water cup, what is the temperature of the water you put in the cup, and what is the feeling I feel. As in the code, the water is placed at different temperatures, and the stability is different, but the cup is the same.

As you can see, the most critical part of this code is this sentence.

new WarmWater();

Read my previous articles should know, I said when speaking polymorphic, will tell a very important point of knowledge-upward transformation.

This code reflects the upward transformation. I will explain this knowledge point in detail later.

Classification of polymorphic

It's easy to understand polymorphism, so let's take a look at polymorphic classifications.

Polymorphism is generally divided into two types: overrides and Overloads . These two points of knowledge in the previous article has been detailed to the results, there is not much to say.

    • Overloaded polymorphic, also called compile-time polymorphism. In other words, this polymorphic recompilation is already determined. Overloading everyone knows that a set of methods with the same method name and a different argument list is overloaded. When this overloaded method is called, different results are obtained by passing in different parameters.

      But there are ambiguities, and some people feel that overloading should not be counted as polymorphic. Because many people's understanding of polymorphism is that the specific type of reference variable defined in the program and the method call made through that reference variable are not deterministic during programming, but are determined during the program's run, which is known as polymorphism. This definition describes our second polymorphic-rewrite polymorphism. Also, overloaded polymorphism is not unique to object-oriented programming, but polymorphism is one of the three main features of object-oriented (if I'm wrong, remember to tell me.) )。

      I don't think it's necessary for us to go into these definitions, and my understanding is that the ability to have many different forms or forms of the same behavior is polymorphic, so I think overloading is also a polymorphic, and if you disagree with that view, I accept it.

    • Rewrite polymorphic, also called run-time polymorphism. This polymorphism is implemented by dynamic binding, which refers to the actual type of the referenced object during execution and invokes its corresponding method according to its actual type. That is, only if the program is running, do you know which subclass of the method is called.
      This polymorphism is achieved through the rewriting of functions and the upward transformation, and the example in our code above is a complete rewrite polymorphism. All of the polymorphic states we're going to talk about are rewrite-polymorphic, because it's really polymorphic in object-oriented programming.

      Dynamic binding technology involves the JVM, temporarily do not speak (because I do not understand, haha haha), interested can study on their own, I do not have time to study the JVM.

conditions of polymorphism

As I said earlier, the polymorphic we're going to say is run-time polymorphic.

    • inheritance . There must be a subclass and parent of the inheritance relationship in the polymorphic.
    • rewritten . Subclasses redefine some of the methods in the parent class and call the methods of the subclasses when they are called.
    • upward Transformation . A reference to a subclass needs to be assigned to the parent class object in polymorphism, so that the reference can have the method that the skill calls the parent class's methods and subclasses.

Inheritance can also be replaced by implementing an interface.

Inheritance and rewriting have all been said before, so let's look at what transformation is.

Upward transformation and downward transformation Upward Transformation

The object that the subclass refers to is converted to a parent class type called upward transformation. In layman's words, a subclass object is converted to a parent class object. The parent class object can be an interface here.

Case-driven

Let's look at an example that everyone knows:

 Public  class Animal {     Public void Eat() {System.out.println ("Animal eatting ..."); }} Public  class Cat extends Animal{     Public void Eat() {System.out.println ("I eat fish."); }} Public  class Dog extends Animal{     Public void Eat() {System.out.println ("I eat bones."); } Public void Run() {System.out.println ("I'll run."); }} Public  class Main {     Public Static void Main(string[] args) {Animal Animal =NewCat ();//Upward TransformationAnimal.eat (); Animal =NewDog ();    Animal.eat (); }}//Results://I eat fish//I eat Bones

This is the upward transformation, Animal Animal = new Cat (), and the subclass object Cat into the parent class object Animal. This time animal the method called by the reference is a subclass method.

The order of the method calls is explained in more detail later.

issues needing attention in the process of transformation
    • When you move up, the methods that are defined by subclasses are lost. For example, the Run method defined in the above dog class, when the animal reference to the dog class instance is not accessible to the Run method, animal.run() will error.
    • The subclass reference cannot point to the parent class object. Cat c = (Cat)new Animal()This is not going to work.
Benefits of upward transformation
    • Reduce duplication of code and make your code concise.
    • Improve system scalability.

For example: I now have many kinds of animals, to feed them to eat things. If you don't have to move up, then I need to write this:

publicvoideat(Cat c){    c.eat();}publicvoideat(Dog d){    d.eat();}//......eat(new Cat());eat(new Cat());eat(new Dog());//......

An animal to write a method, if I have 10,000 kinds of animals, I will write 10,000 methods, after writing about SE years have been several. Well, you are very good, you have to finish writing, thought you can relax for a while, suddenly came a new kind of animal, do you have to write a eat method for it alone? Are you happy?

What if I use upward transformation? All I need to do is write:

publicvoideat(Animal a){    a.eat();}eat(new Cat());eat(new Cat());eat(new Dog());//.....

Yes, it's done. Does the code have a lot of brevity? And this time, if I have a new animal to add, I just need to implement its own class, let him inherit animal, and do not need to write a eat method for it alone. Does it increase scalability?

Down Transformation

and the upward transformation of the corresponding is the downward transformation. The downward transformation transforms the parent object into a subclass object. (Please note!) There's a hole in here. )

Case-driven

Let's look at an example:

//还是上面的animal和cat dognew Cat();Cat c = ((Cat) a);c.eat();//输出  我吃鱼Dog d = ((Dog) a);d.eat();// 报错 : java.lang.ClassCastException:com.chengfan.animal.Cat cannot be cast to com.chengfan.animal.Dognew Animal();Cat c1 = ((Cat) a1);c1.eat();// 报错 : java.lang.ClassCastException:com.chengfan.animal.Animal cannot be cast to com.chengfan.animal.Cat

Why does the first piece of code not error? As you know, because A is a cat object in itself, so it's a matter of course to turn down to cat, and for granted it can't be turned into dog, you've seen a dog suddenly become a cat this motherfucker phenomenon?

A1 is a animal object, and it cannot be transformed downward to any subclass object. For example, you go to archaeology, you find a new creature, you know it's an animal, but you can't just say, ah, it's a cat, or it's a dog.

Down Transition Considerations
    The premise of
    • transformation downward is that the parent object points to a subclass object (that is, it has to be transformed upward before it goes down)
    • The downward transformation can only be transformed into this class of objects (cats cannot become dogs).

      Maybe you would say, "I'm sick, I'm going to move up and then up?"

      We go back to the question: feed the animals, eat, and do something? Different animals must do different things, how to do it?

publicvoideat(Animal a){    ifinstanceof Dog){          Dog d = (Dog)a;        d.eat();        d.run();//狗有一个跑的方法          }     ifinstanceof Cat){          Cat c = (Cat)a;        c.eat();        System.out.println("我也想跑,但是不会"//猫会抱怨        }     a.eat();//其他动物只会吃}eat(new Cat());eat(new Cat());eat(new Dog());//.....

Now, do you understand? This is the simple application of the downward transformation, which may be an inappropriate example, but it can also illustrate some of the problems.

Knock on the blackboard and draw the key! Did you see that instanceof ?

Classic Case Analysis Polymorphism

Basic polymorphism and transformation we're all going to end up with a little meal. See a classic case:

Class A { PublicStringShow(D obj) {return("A and D"); } PublicStringShow(A obj) {return("A and a"); }}class B extends a{ PublicStringShow(B obj) {return("B and B"); } PublicStringShow(A obj) {return("B and A"); }}class C extends B{}class D extends b{} Public  class Demo {     Public Static void Main(string[] args) {A A1 =NewA (); A A2 =NewB (); b b =NewB (); c C =NewC (); D d =NewD (); System.out.println (" the"+ a1.show (b)); System.out.println ("2--"+ a1.show (c)); System.out.println ("3--"+ a1.show (d)); System.out.println ("4--"+ a2.show (b)); System.out.println ("5--"+ a2.show (c)); System.out.println ("6--"+ a2.show (d)); System.out.println ("7--"+ b.show (b)); System.out.println ("8--"+ b.show (c)); System.out.println ("9--"+ b.show (d)); }}//Results://1--a and A//2--a and A//3--a and D//4--b and A//5--b and A//6--a and D//7--b and B//8--b and B//9--a and D//Can you read the result? Let's start with a self-analysis. 

The first three, forced analysis, but also can read. But the fourth one, maybe you're stupid. Why not B and B?

We're going to learn something new here.

When a parent class object references a variable that references a subclass object, the type of the referenced object determines which member method to call, and the reference variable type determines the callable method. If the method is not overridden in a subclass, it is looked for in the parent class.

It might be a bit of a mouthful to read, so let's start with a simple example:

 class X {     Public voidShow (Y y) {System.out.println ("x and Y"); } Public voidShow () {System.out.println ("only X"); }} class Y extends X {     Public voidShow (Y y) {System.out.println ("Y and Y"); } Public voidShowinti) {}} class main{     Public Static voidMain (string[] args) {x x =NewY (); X.show (NewY ());    X.show (); }}//Results//y and y//only x

Y inherits X, overwrites the show (Y Y) method in X, but does not overwrite the show () method.

At this point, the reference to X for x refers to the object Y, and at this point the method called is determined by Y, which is looked up first from Y. Execution x.show(new Y()); , the method is defined in Y, so the method in Y is executed;

But x.show(); when it's done, some people will say, Y doesn't have this method? It seems to be looking for the method in the parent class because the method in X is called.

In fact, there is a show () method in the Y class, this method inherits from X, but does not overwrite the method, so it is not explicitly written in Y, it looks like the method called in X, actually called in Y.

It's not hard to understand the hard-to-understand words at this time. X is a reference variable type, which determines which methods can be called, Show () and show (Y y) can be called, and show (int i) cannot be called. Y is the type of the referenced object that determines whose method to call: The method that calls Y.

The above is a simple knowledge, it is not enough to let us understand the complex example. Let us look at such a knowledge:

The priority of the invocation of an object method in the inheritance chain: This.show (O), Super.show (O), This.show (Super) O, Super.show ((Super) O).

If you can understand this invocation relationship, then polymorphism you have mastered. Let's go back to that complex example:

The ABCD relationship is like this:c/d-> b-> A

Let's first analyze 4:a2.show(b)

  • First, A2 is a reference type of type A, which points to an object of type B. A determines the callable methods: Show (D obj) and show (A obj).
  • a2.show(b)==> this.show(b) , here This refers to B.
  • And then. Find Show (b obj) in class B, but it's useless because the show (b obj) method is not in the callable range, this.show(O) fails, and goes to the next level: super.show(O) , super refers to a.
  • Find Show (B obj) in a, failed because this method is not defined. Enter the third level: this.show((super)O) , this refers to B.
  • In B, look for Show ((a) O), find: Show (a obj), choose to call the method.
  • Output: B and A

If you can understand the process, and can analyze other situations, then you really have mastered it.

Let's take another look at 9:b.show(d)

  • First, B is a reference object of type B, pointing to an object of type B. Does not involve an upward transformation, only the methods in this class are called.
  • In B, look for show (D obj), method. Now you're not going to say you haven't found it, are you? Found, call the method directly.
  • Output A and D.
Summarize

This is basically what this article is about. Let's sum it up.

    1. Polymorphism, in short, is the ability of the same behavior to have many different manifestations or forms.
    2. Polymorphic classification: Run-time polymorphism and compile-time polymorphism.
    3. Prerequisites for Runtime Polymorphism: Inheritance (Implementation), rewriting, upward transformation
    4. Transform up and down.
    5. The priority of the invocation of an object method in the inheritance chain: This.show (O), Super.show (O), This.show (Super) O, Super.show ((Super) O).

In fact, when you use the upward transformation, you use polymorphism. There are some other points of knowledge about polymorphism, such as several keywords: static, final, and so on, which we'll explain later. The next "re-understanding Java (vi)--java in the alternative: static keyword" is not updated regularly.

If there is anything wrong with the content of the article, or if something goes wrong, please contact me in time. The content of the article is not guaranteed to be completely correct. If you have a better concise or better understanding of the way, welcome to communicate together.

Original address: http://blog.csdn.net/qq_31655965/article/details/54746235
Welcome Reprint ~ Reprint Please indicate the source!
After reading a little bit of praise Bai ~

Re-understanding Java (v)----Object-oriented polymorphism (upward transformation and downward transformation)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.