Home  >  Article  >  Java  >  Things to note when using Java polymorphism

Things to note when using Java polymorphism

高洛峰
高洛峰Original
2017-01-19 14:02:411419browse

How is polymorphism implemented in Java?
Polymorphism in Java, like C++, is achieved through late binding or runtime binding. When a method referenced by an object is called, the compiler does not know whether the reference points to the type object specified when the variable was declared, or an object of a subclass of that type. Therefore the compiler cannot bind to a specific method for this call. It can only be bound to a specific method at runtime through runtime type identification (RTTI) in Java. The following is a specific example:

class shape
{
    public void draw()
    {
   print("shape");
    }
}
class triangle extends shape
{
    public void draw()
    {
   print("triangle");
    }
}
public class Polymorphism {
public static void main(String[] args)
{
    shape s=new triangle();
    s.draw();
}

The result is that triangle
s is a shape reference, but at runtime because it is a triangle object, the draw method of triangle is still called.


Some pitfalls in Java polymorphism

Overriding private methods?
Private methods cannot be overridden in Java. This is actually easy to understand, because private methods are not visible in subclasses. Subclasses do not inherit the private methods of the parent class, let alone override them. Therefore, the method with the same name in the subclass is a completely new method.

public class Polymorphism {
    private void show()
    {
   print("show parent");
    }
public static void main(String[] args)
{
    Polymorphism p=new privateMethod();
    p.show();
}
}
class privateMethod extends Polymorphism
{
    public void show()
    {
   print("show derived");
    }
}

The result is polymorphism of show parent

fields and static methods?
Subclasses can inherit the non-private fields of the parent class. Are the fields of the subclass also polymorphic? Let's take a look at a practical example:

class shape
{
    protected int perimeter=1;
    public void draw()
    {
   print("shape");
    }
    public int getPerimeter()
    {
   return perimeter;
    }
}
class triangle extends shape
{
int perimeter=3;
    public void draw()
    {
   print("triangle");
    }
    public int getPerimeter()
    {
   return perimeter;
    }
    public int getSuperPerimeter()
    {
   return super.perimeter;
    }
}
public class Polymorphism {

public static void main(String[] args)
{
    shape s=new triangle();
    print("s.perimeter:"+s.perimeter);
    print("s.getperimeter:"+s.getPerimeter());
    triangle t=new triangle();
    print("t.perimeter:"+t.perimeter);
    print("t.getperimeter:"+t.getPerimeter());
    print("t.getsuperperimeter:"+t.getSuperPerimeter());
}
}

This operation result contains the following information:
1. After the triangle object is transformed up to shape, direct access to the fields is determined by the compiler, so it will not show Out of polymorphism, 1 is returned.
2. After the triangle object is transformed up to shape, the method to access the field is called. The triangle's getperimeter method is called based on the runtime object type delayed binding, and the returned value is 3
3.t The object contains two perimeters. Fields, one comes from itself and one comes from its parent class. At the same time, when the field is called with the field name, its own perimeter field is returned by default. To call the field inherited from the parent class, use the super.perimeter method.
This result seems a little confusing. In order to avoid this situation, we generally declare the fields as private (subclasses cannot inherit). At the same time, it is best not to declare fields in subclasses. Same name as a field inherited from the parent class.
Static methods do not have polymorphism, because static methods are bound to classes, and there is no situation where the specific type is not known.


Polymorphism of constructor?
The constructor is not polymorphic, because the constructor method itself is a static method (if not, it will fall into an endless loop of chicken laying eggs and eggs laying eggs). To introduce our problem, let's first look at the order in which the constructor is called.
1. The storage space allocated for this object is initialized to 0 (the object is initialized to null)
2. The constructor of the parent class is called (this ensures that the fields accessed in the constructor of the subclass are initialized )
3. Member variable initialization
4. Constructor call of subclass

Now suppose that in the second step, we call a certain method in the constructor of the parent class, this Is the method polymorphic? Let's look at a specific example:

class shape
{
    protected int perimeter=1;
    public shape()
    {
   draw();
   print("shape created");
    }
    public void draw()
    {
   print("draw shape "+perimeter);
    }

}
class triangle extends shape
{
int perimeter=3;
public triangle()
{
    print("triangle created");
}
    public void draw()
    {
   print("draw triangle "+perimeter);
    }
    public int getPerimeter()
    {
   return perimeter;
    }
}
public class Polymorphism {

public static void main(String[] args)
{
    shape s=new triangle();
}
}

We can see that although the triangle object has not been constructed yet, the draw method is still dynamically bound to the triangle's draw method. Also notice that the value of perimeter has not been initialized to 3, but to 0.

The result is that we access the fields in the triangle object before it is initialized. Therefore, in actual applications, we must avoid calling other methods in the constructor, or only call private methods (which will not be inherited, so this problem will not occur)

More Java polymorphism usage precautions are related Please pay attention to the PHP Chinese website for articles!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn