Easy Tutorial
❮ Awk Arrays Const Char ❯

Polymorphism in Java

Category Programming Techniques

Polymorphism is generally divided into two types: overriding polymorphism and overloading polymorphism.

-

Overloading Polymorphism, also known as compile-time polymorphism. This means that this type of polymorphism is determined at compile time. Overloading is well-known; a set of methods with the same name but different parameter lists is considered overloading. When calling an overloaded method, different results are obtained by passing different parameters.

>

However, there is ambiguity here. Some people believe that overloading should not be considered polymorphism. Many people's understanding of polymorphism is: the specific type that the reference variable defined in the program points to, and the method call made through this reference variable, are not determined during programming, but are determined at runtime. This situation is called polymorphism. This definition describes our second type of polymorphism—overriding polymorphism. Moreover, overloading polymorphism is not unique to object-oriented programming, while polymorphism is one of the three main features of object-oriented programming (if I'm wrong, please let me know...).

I don't think it's necessary to delve into these definitions. My understanding is: the ability of the same action to have multiple different manifestations or forms is polymorphism. Therefore, I believe that overloading is also a form of polymorphism. If you disagree with this view, I accept that.

-

Overriding Polymorphism, also known as runtime polymorphism. This type of polymorphism is implemented through dynamic binding technology, which means that the actual type of the referenced object is determined during execution, and the corresponding method is called based on its actual type. That is, only when the program runs, you know which subclass method is being called.

This polymorphism is achieved through method overriding and upcasting. The example in our code above is a complete case of overriding polymorphism. All the polymorphism we will discuss next is overriding polymorphism, as it is the true polymorphism in object-oriented programming.

Upcasting

Converting a subclass reference to a superclass type is called upcasting. Simply put, it is converting a subclass object to a superclass object. The superclass object here can be an interface.

Consider a well-known example:

Example

public class Animal {
    public void eat(){
        System.out.println("animal eatting...");
    }
}

public class Cat extends Animal{

    public void eat(){
        System.out.println("我吃鱼");
    }
}

public class Dog extends Animal{

    public void eat(){
        System.out.println("我吃骨头");
    }

    public void run(){
        System.out.println("我会跑");
    }
}

public class Main {

    public static void main(String[] args) {
        Animal animal = new Cat(); // Upcasting
        animal.eat();

        animal = new Dog();
        animal.eat();
    }
}

// Result:
// 我吃鱼
// 我吃骨头

This is upcasting, Animal animal = new Cat(); converts the subclass object Cat to the superclass object Animal. At this time, the method called by the reference animal is the subclass method.

Issues to be aware of during casting

Benefits of upcasting

Downcasting

The opposite of upcasting is downcasting. Downcasting is converting a superclass object to a subclass object. (Be careful! There are pitfalls here.)

Case-driven

Consider an example:

// Still using animal, cat, and dog
Animal a = new Cat();
Cat c = ((Cat) a);
c.eat();
// Output: 我吃鱼
Dog d = ((Dog) a);
d.eat();
// Error: java.lang.ClassCastException: com.chengfan.animal.Cat cannot be cast to com.chengfan.animal.Dog
Animal a1 = new Animal();
Cat c1 = ((Cat) a1);
c1.eat();
// Error: java.lang.ClassCastException: com.chengfan.animal.Animal cannot be cast to com.chengfan.animal.Cat

Why doesn't the first block of code report an error? You probably already know, because a is originally a Cat object, so it naturally can be downcast to Cat, and it naturally cannot be converted to Dog. Have you ever seen a dog suddenly turn into a cat?

And a1 is an Animal object, it also cannot be downcast to any subclass object. For example, when you are archaeology, you find a new creature, know it is an animal, but you cannot directly say, oh, it is a cat, or it is a dog.

Downcasting precautions

Consider a classic example:

Example

class A {
    public String show(D obj) {
        return ("A and D");
    }

    public String show(A obj) {
        return ("A and A");
    }

}

class B extends A{
    public String show(B obj){
        return ("B and B");
    }

    public String show(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 = new A();
        A a2 = new B();
        B b = new B();
        C c = new C();
        D d = new D();

        System.out.println("1--" + 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));
    }
}
// Result:
// 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 understand this result? Analyze it yourself first.

The first three, analyzed forcibly, can still be understood. But the fourth one, you might be confused. Why isn't it b and b?

Here we need to learn something new.

>

When a superclass object reference variable references a subclass object, the type of the referenced object determines which member method to call, and the reference variable type determines the callable methods. If the method is not overridden in the subclass, it will look for it in the superclass.

It may be a bit convoluted to read. Let's look at a simple example first:

Example

class X {
    public void show(Y y){
        System.out.println("x and y");
    }

    public void show(){
        System.out.println("only x");
    }
}

class Y extends X {
    public void show(Y y){
        System.out.println("y and y");
    }
    public void show(int i){

    }
}

class main{
    public static void main(String[] args) {
        X x = new Y();
        x.show(new Y());
        x.show();
    }
}
// Result
// y and y
// only x

Y inherits from X, overrides the show(Y y) method in X, but does not override the show() method.

At this time, the reference type is X, and x points to an object of type Y. At this time, the method to be called is determined by Y and will first look in Y. When executing x.show(new Y());, this method is defined in Y, so the method in Y is executed;

But when executing x.show();, some people might say, Y doesn't have this method! It seems to be looking for the method in the superclass, because it calls the method in X.

In fact, Y does have the show() method, which is inherited from X, but it is not overridden in Y, so it is not explicitly written in Y. It looks like it is calling the method in X, but in fact, it is still calling the method in Y.

>

At this point, it's not hard to understand the above difficult sentence, right? X is the reference variable type, which determines which methods can be called; show() and show(Y y) can be called, while show(int i) cannot be called. Y is the type of the referenced object, which determines which method to call: call the method of Y.

The above is a simple knowledge, which is not enough for us to understand that complex example. Let's look at another piece of knowledge:

>

The priority of method calls in the inheritance chain: this.show(O), super.show(O), this.show((super)O), super.show((super)O).

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

The relationship of abcd is as follows: C/D —> B —> A

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

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

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


Summary

This article covers the main points as follows:

>

Source article: http://www.cnblogs.com/kexianting/p/8689031.html

#

-

** huanyouren

* m13**[email protected]

  1. During upcasting, if the subclass does not have certain methods of the superclass, the subclass will automatically inherit all methods of the superclass and can also override them.

  2. In upcasting, if method A is invoked and both the superclass and subclass have this method with the same number, position, and type of parameters, the subclass's method A is called; if only the subclass has method A or invokes an overloaded method of the subclass, and the superclass does not have the corresponding overloaded method (same name but different parameters), an error will occur.

    class Animal {
      public void run(){
        System.out.println("Animal Run");
      }
      public void bark(){
        System.out.println("Animal Bark");
      }
    }
    class Dog extends Animal{
      public void run(){
        System.out.println("Dog Run");
      }
      public void sleep(){
        System.out.println("Dog Sleep");
      }
    }
    public class Test{
      public static void main(String[] args){
        Animal a = new Dog();
        a.run();    // Both Animal and Dog have the run method, so the subclass's run method is used, printing "Dog Run"
        a.bark();   // The bark method is only in the Animal superclass, but the subclass Dog inherits it, so it prints "Animal Bark"
        a.sleep();  // The sleep method is not in the Animal superclass but only in the Dog subclass, so it will cause an error, but can be successfully printed after downcasting
        ((Dog)a).sleep();  // Casting from Animal back to Dog class, prints "Dog Sleep"
      }
    }
    

** huanyouren

* m13**[email protected]

** Click to share notes

Cancel

-

-

-

❮ Awk Arrays Const Char ❯