Polymorphism in Java

Source: Internet
Author: User

1. Upstream Stylingwe have known before that an object is used as its own type, or as an object of its underlying type. The behavior of getting an object handle and using it as the underlying type handle is called "upstream styling"-because the inheritance tree is drawn as the base class is at the top. However, this will also encounter a problem, as shown in the following example:
Inheritance & upcastingclass Note {private int value;private note (int val) {value = val;} public static final Note Middlec = new Note (0), CSharp = new Note (1), Cflat = new Note (2);} Etc.class Instrument {public void play (Note N) {System.out.println ("Instrument.play ()");}} Wind objects is instruments//because they has the same interface:class wind extends instrument {//Redefine INTERFAC e method:public void Play (Note N) {System.out.println ("Wind.play ()");}} public class Music {public static void tune (instrument i) {//... i.play (Note.middlec);} public static void Main (string[] args) {Wind flute = new Wind (); Tune (flute);//Upcasting}}

Output Result:Wind.play ()

Wherein, the method Music.tune () receives a instrument handle, and also receives everything derived from the instrument. This can happen when a wind handle is passed to tune ().

2. Why go back to stylingIf you let tune () simply get a wind handle and use it as your own argument, it would seem much simpler and more intuitive. But note that if you do that, you need to write a new tune () for each type of instrument in the system. Suppose that the two instrument (musical instruments), stringed (string) and brass (brass), are added according to the preceding inference:
overloading instead of Upcastingclass Note2 {private int value;private Note2 (int val) {value = val;} public static final Note2 Middlec = new Note2 (0), CSharp = new Note2 (1), Cflat = new Note2 (2);} Etc.class Instrument2 {public void play (Note2 N) {System.out.println ("Instrument2.play ()");}} Class Wind2 extends Instrument2 {public void play (Note2 N) {System.out.println ("Wind2.play ()");}} Class Stringed2 extends Instrument2 {public void play (Note2 N) {System.out.println ("Stringed2.play ()");}} Class Brass2 extends Instrument2 {public void play (Note2 N) {System.out.println ("Brass2.play ()");}} public class Music2 {public static void tune (Wind2 i) {i.play (Note2.middlec);} public static void Tune (Stringed2 i) {i.play (Note2.middlec);} public static void Tune (Brass2 i) {i.play (Note2.middlec);} public static void Main (string[] args) {Wind2 flute = new Wind2 (); Stringed2 violin = new Stringed2 (); Brass2 Frenchhorn = new Brass2 (); Tune (flute); No Upcastingtune (violin); tune (Frenchhorn);}}

This certainly works, but there is a huge drawback: you must write a method that is closely related to the class for each new Instrument2 class. This means that the first time requires much more programming volume. Later, if you want to add a new method like tune () or add a new type for instrument, you still need to do a lot of coding work. In addition, the compiler will not prompt for any errors even if you forget to override one of your own methods. In this way, the entire operation of the type is extremely difficult to manage, with a risk of runaway. But wouldn't it be much easier to write a method that would use the base class as an argument or a parameter instead of using those specific derivative classes? In other words, if we can ignore the derivative class and only let our own code to deal with the base class, then the amount of work saved will be difficult to estimate. This is where the "polymorphism" is.

3, further understanding of the molding typeThe shape example has a base class named shape, plus a number of derived types: Circle (circle), Square (square), Triangle (triangle), and so on. People like this example because it's easy to understand concepts like "a circle is a type of shape."
The following succession diagram shows us their relationship:


The following statement can be used to simply show:
Shape s = new Circle ();
Here, we create the Circle object and assign the result handle to a shape immediately. The surface seems to belong to the wrong operation (assigning one type to another), but it is practically feasible-because, according to the inheritance, Circle belongs to shape. So the compiler recognizes the above statement and does not prompt us for an error message.
When we call one of the underlying class methods (already overridden in a derived class): S.draw ();
Similarly, you might think that you would call shape's draw (), because this is a shape handle after all. So how does the compiler know what to do with everything else? But this is actually called Circle.draw (), because late binding is already involved (polymorphism).
Late binding: The binding takes place during run time, based on the type of the object. The following example illustrates the problem from a slightly different angle:
Polymorphism in javaclass shape {void Draw () {}void erase () {}}class Circle extends Shape {void Draw () {System.out.print ln ("Circle.draw ()");} void Erase () {System.out.println ("circle.erase ()");}} Class Square extends Shape {void Draw () {System.out.println ("Square.draw ()");} void Erase () {System.out.println ("square.erase ()");}} Class Triangle extends Shape {void Draw () {System.out.println ("Triangle.draw ()");} void Erase () {System.out.println ("triangle.erase ()");}} public class Shapes {public static Shape Randshape () {switch (int) (Math.random () * 3)} {default://To quiet the compile Rcase 0:return New Circle (), Case 1:return New Square (), Case 2:return new Triangle ();}} public static void Main (string[] args) {shape[] s = new shape[9];//Fill up the array with shapes:for (int i = 0; I < s . length; i++) S[i] = Randshape ();/Make polymorphic method calls:for (int i = 0; i < s.length; i++) S[i].draw ();}}

Operation Result:
in the main class shapes, a static method named Randshape () is included. Its purpose is to generate a handle for a randomly selected shape object each time it is called. Please note that the upstream styling occurs in each return statement. This statement takes a handle to a circle,square or triangle and sends it as a return type shape to the method. So whenever you call this method, you never get a chance to know exactly what the exact type is, because there's a simple shape handle. Main () contains an array of shape handles, where the data is filled in by a call to Randshape (). At this point, we know that we have shape, but we don't know any specifics (the compiler does not know). However, when we step in this array and call draw () for each element, the correct behavior associated with each type will magically occur, resulting in the result of the above operation.
4. Extensibilitynow, let's still return to the instrument (instrument) example. Because of the polymorphism, you can add as many new types as you want to the system without changing the True () method. In a well-designed OOP program, most or all of our methods follow the model of tune () and only communicate with the underlying class interface. We say that such a program is "extensibility" because new data types can be inherited from a common base class to add functionality. If it is to accommodate the requirements of the new class, then the method of manipulating the underlying class interface does not need to be changed at all.
For an example of a musical instrument, suppose we add more methods to the base class, and a series of new classes, what will happen? Here are the following:

All of these new classes can work with the old class--tune () without any adjustment to tune (). Even if tune () is in a separate file, and the new method is added to the Instrument interface, tune () works correctly and does not need to be recompiled. The following procedure is a specific implementation of the above:
An extensible Programimport java.util.*;class Instrument3 {public void play () {System.out.println ("Instrument3.play ( )");} Public String What () {return "Instrument3";} public void adjust () {}}class Wind3 extends Instrument3 {public void play () {System.out.println ("Wind3.play ()");} Public String What () {return "Wind3";} public void adjust () {}}class Percussion3 extends Instrument3 {public void play () {System.out.println ("Percussion3.play ( )");} Public String What () {return "Percussion3";} public void adjust () {}}class Stringed3 extends Instrument3 {public void play () {System.out.println ("Stringed3.play ()");} Public String What () {return "Stringed3";} public void adjust () {}}class BRASS3 extends Wind3 {public void play () {System.out.println ("Brass3.play ()");} public void adjust () {System.out.println ("brass3.adjust ()");}} Class Woodwind3 extends Wind3 {public void play () {System.out.println ("Woodwind3.play ()");} Public String What () {return "Woodwind3";}} public class Music3 {//doesn ' t care about TyPE, so new types//added to the system still work right:static void tune (Instrument3 i) {//... i.play ();} static void Tuneall (instrument3[] e) {for (int i = 0; i < e.length; i++) tune (E[i]);} public static void Main (string[] args) {instrument3[] Orchestra = new Instrument3[5];int i = 0;//upcasting during additio N to the array:orchestra[i++] = new Wind3 (); orchestra[i++] = new Percussion3 (); orchestra[i++] = new Stringed3 (); orchestra[ i++] = new BRASS3 (); orchestra[i++] = new Woodwind3 (); Tuneall (orchestra);}}
In main (), when we place something in the Instrument3 array, we automatically go back to the Instrument3. As you can see, all the other code around the tune () method changes while the tune () method is unaffected by them and works unchanged properly. This is exactly what you want to achieve with the shape of polymorphism. After we modify the code, we do not affect the parts of the program that should not be affected. In addition, we believe that polymorphism is a critical technology that allows programmers to "separate things that have changed from what has not changed".





Polymorphism in Java

Related Article

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.