Getting Started with Java (ii): upward transformation and downward transformation

Source: Internet
Author: User
Tags export class

In the process of Java learning, for the transformation of this operation is more confused, especially summed up this article. Examples refer to "Java Programming ideas".

Directory

Several synonyms

Upward transformation and downward transformation

Example one: Upward transformation, invoking the specified parent class method

Example two: Upward transformation, dynamic binding

Example three: Upward transformation, static binding

Example four: Downward transformation

The misunderstanding of transformation

1. Operational information (RTTI)

2. Array type

3.Java container

several synonyms

The first is a few sets of synonyms, because of the different use of different books, is one of the reasons for confusion.

Parent class/Superclass/base class

Subclass/Export class/inheriting class/derived class

static binding/Early binding

Dynamic binding/Late binding/run-time binding

toontransformation and tounderTransformationExample One: upward transformation, invoking the specified parent class method
classShape {
  Static voidDraw (Shape s) {System.out.println ("Shape draw."); }}classCircleextendsShape {
Static voidDraw (Circle c) {System.out.println ("Circle draw."); }} Public classCasttest { Public Static voidMain (String args[]) {Circle C=NewCircle (); Shape.draw (c); }}

Output to

Shape draw.

This indicates that the draw (shape s) method was originally designed to accept the shape reference, but the circle reference was passed here. Actually the draw (shape s) method can be used for all the export classes of the Shape class, which is called upward transformation. Behave in a manner consistent with the category in which the method belongs. in other words, because the method of the parent shape is clearly pointed out, its behavior is necessarily the corresponding behavior of the method, without any ambiguity.

The "Move Up" naming comes from the drawing of the class inheritance graph: The root is placed at the top, and then gradually downward, as in the example of two classes in this case, as shown in:

Example Two: upward transformation, dynamic binding
classShape { Public voidDraw () {System.out.println ("Shape draw."); }}classCircleextendsShape { Public voidDraw () {System.out.println ("Circle draw."); }} Public classCasttest { Public Static voidDrawintest (Shape s) {S.draw (); }     Public Static voidMain (String args[]) {Circle C=NewCircle ();    Drawintest (c); }}

Output to

Circle draw.

The reason for this is that a drawintest (shape s) can handle all the subclasses of a shape without having to provide its own method for each subclass. However, this method can invoke methods common to both the parent and subclass, and even if they behave in a inconsistent manner, they will only show the behavior of the corresponding subclass method. This is allowed by polymorphism, but is prone to confusion.

example Three: upward transformation, static binding
classShape {     Public Static voidDraw () {System.out.println ("Shape draw."); }}classCircleextendsShape {     Public Static voidDraw () {System.out.println ("Circle draw."); }} Public classCasttest { Public Static voidDrawintest (Shape s) {S.draw (); }     Public Static voidMain (String args[]) {Circle C=NewCircle ();Drawintest (c); }}

Output to

Shape draw.

What is the difference between example three and example two? A closer look reveals that the method called in the example three-way is modified by static, resulting in a completely different result.

The reasons for these two behavioral differences are thatin addition to the static and final methods in Java, including private methods, other methods are dynamically bound. for an incoming base class reference, late binding correctly identifies the export class to which it belongs. Added to the static, naturally not get this effect.

Once you understand this, you can see why you have to write the example. The code in example one explicitly indicates the invocation of the parent class method, and the example three calls which method is statically bound, not directly indicated, a little bit around.

example four: downward transformation

From the Java Programming thought 8.5.2 section, a slight modification was made to show how to obtain access to the subclass's unique methods through type conversion.

This is equivalent to telling the compiler additional information that the compiler will examine accordingly.

classUseful { Public voidF () {System.out.println ("f () in useful");}  Public voidG () {System.out.println ("g () in useful"));}}classMoreusefulextendsUseful { Public voidF () {System.out.println ("f () in Moreuseful");}  Public voidG () {System.out.println ("G () in Moreuseful"));}  Public voidU () {System.out.println ("U () in moreuseful"));}} Public classRTTI { Public Static voidMain (string[] args) {useful[] x= {            Newuseful (),Newmoreuseful ()}; x[0].f (); x[1].g (); //Compile-time:method not found in useful://! x[1].u ();((moreuseful) x[1]). U ();//Downcast/rtti((moreuseful) x[0]). U ();//Exception Thrown    }}    

Output

Exception in thread "main" java.lang.ClassCastException:Useful cannot is cast to moreuseful
At Rtti.main (rtti.java:44)
f () in useful
g () in moreuseful
U () in moreuseful

  Although the parent class useful type x[1] receives a reference to a subclass Moreuseful object, it still cannot directly invoke the U () method in its subclass. If you need to call, you need to do a downward transformation. This usage is very common, such as a common method, the processing of the entry is a parent class, processing, according to the type information into the corresponding subclass using different logical processing.

In addition, the parent object cannot be converted down to a subclass object .

The benefits of downward transformation are evident when learning about interfaces (if you think of implementing interfaces as multiple inheritance). You can refer to the example of section 9.4, which is not detailed here:

InterfaceCanfight {voidfight ();}InterfaceCanswim {voidswim ();}InterfaceCanfly {voidfly ();}classActioncharacter { Public voidfight () {}}classHeroextendsActioncharacterImplementscanfight, Canswim, canfly { Public voidswim () {} Public voidfly () {}} Public classAdventure {Static voidt (canfight x) {x.fight ();} Static voidu (canswim x) {x.swim ();} Static voidV (canfly x) {x.fly ();} Static voidW (actioncharacter x) {x.fight ();}  Public Static voidMain (string[] args) {Hero I=NewHero (); T (i); //Treat it as a canfightU (i);//Treat it as a canswimV (i);//Treat it as a canflyW (i);//Treat It as an actioncharacter    }}

the misunderstanding of transformation

Transformation is convenient, and using transformation can write flexible code. However, if the use of arbitrary and carried away, it will inevitably fall. Here are a few things that appear to be transformational and actually lead to errors.

1. Operational information (RTTI)
/**/Classint. class

This code is invalid, the compilation does not pass, even if the int to the integer also does not pass. Although the wrapper class for int is the subclass of number, the integer class object is not a subclass of the number class object.

2. Array type
/*The code section overrides the Java Programming thought 15.8.2 section, which is not relevant to generics or not. */classGeneric<t> {} Public classArrayofgeneric {Static Final intSIZE = 100; StaticGeneric<integer>[] Gia; @SuppressWarnings ("Unchecked")     Public Static voidMain (string[] args) {//gia = (generic<integer>[]) new object[size];Gia = (generic<integer>[])NewGeneric[size]; }}

 The comment section, which runs after the comment is removed, prompts java.lang.ClassCastException. The confusing part here is that the subclass array type is not a subclass of the parent array type . After the exception prompt, you can see

[Ljava.lang.Object; Cannot is cast to [Lgeneric;

In addition to the exception information that is output through the console, you can use the following code to see what kind of Gia is:

        New object[size];         New Generic[size];        System.out.println (Obj.getclass (). GetName ());        System.out.println (Gia.getclass (). GetName ());        System.out.println (Obj.getclass (). GetClass (). GetName ());        System.out.println (Gia.getclass (). Getsuperclass (). GetName ());

The console output is:

[Ljava.lang.Object;
[Lgeneric;
Java.lang.Object
Java.lang.Object

As can be seen, GIA and obj, defined by generic<integer>[] gia and object[] obj, do not have any inheritance at all, and naturally cannot type conversions, regardless of whether the object in this array is a subclass. (Subclass object can be obtained by upward transformation, if it is really a subclass object, see example IV)

3.Java Container
/*code excerpt from "Java Programming thought" section 15.10*/classFruit {}classAppleextendsFruit {}classOrangeextendsFruit {} Public classTest { Public Static voidMain (string[] args) {//cannot compileList<fruit> fruitlist =NewArraylist<apple>(); }}

Why is the assignment failed when the list of fruit is able to store Apple objects? In fact, this is not an upward transformation. Although it is possible to learn list<fruit> and list<apple> through GetClass (). GetName () The genus Java.util.ArrayList type, however, assumes that it can be compiled here, equivalent to allowing an orange object to be stored to arraylist<apple>, which is obviously unreasonable. Although the generic erase,arraylist<fruit> and arraylist<apple> are the same type at run time, the type of element that can be held is checked at compile time.

Getting Started with Java (ii): upward transformation and downward transformation

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.