banner
lMingyul

lMingyul

记录穿过自己的万物
jike

Overloading and Overriding

Record some notes on learning Java.

Overloading#

Overloading: Overloading refers to method overloading, where two or more methods have the same name.

Classic Overloading Methods#

Overloading is often used in constructor methods because the role of a constructor is to initialize the construction of an object. The name of the constructor must be the same as the class name, which forms a classic pair of overloaded methods: the parameterless constructor and the parameterized constructor.

Here is an example:

public class User {

    private Integer id;

    private String userName;
		
  	// Parameterless constructor
    public User() {
    }
		
  	// Constructor with a single parameter
    public User(Integer id) {
        this.id = id;
    }

  	// Constructor with all parameters
    public User(Integer id, String userName) {
        this.id = id;
        this.userName = userName;
    }

}

Why Overloading is Needed#

We all know that the most important concept in Java is: objects. Methods are the behaviors of objects. An object can perform the same named behavior but do different things, for example: Xiao Ming playing mahjong.

Literal meaning: Xiao Ming is playing mahjong with others as a recreational activity.

Other meanings: Xiao Ming is "hitting" a person named "mahjong".

Therefore, the ambiguity in natural language can also occur in code.

For example, when a person is eating, whatever I give him, he is eating it. If I give him noodles, his behavior is eating noodles. If I give him rice, he is eating rice. But his behavior is called eating.

In summary, overloading is necessary in code.

Distinguishing Overloaded Methods#

If different methods have the same name, how do we distinguish them?

The important principle for distinguishing overloading is that each overloaded method must have a unique parameter type list (i.e., each method has different input parameters from other methods).

Where are the differences in the parameter list?

Differences in Parameter Types#

public class Test {

    public static void main(String[] args) {
      	// The different types of age can distinguish between two methods with the same name
        getPerson("mingyu", 18);
        getPerson("mingyu", "18");
    }

    static void getPerson(String name, int age) {
        System.out.println("name: " + name + ", " + "int_age: " + age);
    }

    static void getPerson(String name, String age) {
        System.out.println("name: " + name + ", " + "String_age: " + age);
    }

}

Output:

name: mingyu, int_age: 18
name: mingyu, String_age: 18

Differences in Parameter Order#

Although distinguishing overloaded methods by parameter order is possible, it is not recommended to use this method of distinction because it is difficult to maintain the code in this way.

public class Test {

    public static void main(String[] args) {
        getPerson("mingyu", 18);
        getPerson(18,"mingyu");
    }

    static void getPerson(String name, int age) {
        System.out.println("name: " + name + ", " + "behind_age: " + age);
    }

    static void getPerson(int age, String name) {
        System.out.println("name: " + name + ", " + "first_age: " + age);
    }

}

Output:

name: mingyu, behind_age: 18
name: mingyu, first_age: 18

Distinguishing Overloaded Methods by Return Value#

In addition to the types and order of parameters, can we distinguish overloaded methods by the return value of the method?

The answer is no, as shown in the example below.

 void f() {}
    
 int f() { return 1; }

When we only want to call the f() method without needing its return value (such as the System.out.println method), if we only call the f() method, Java cannot distinguish which method we need to call.

Overloading of Primitive Types#

For overloaded methods with only different primitive types, there may be a situation where the smaller type can be automatically promoted to a larger type.

public class Test {

    public static void main(String[] args) {
        int x = 5;
        checkBasicTypes(x);
    }

    static void checkBasicTypes(long x) {
        System.out.println("Type long: " + x);
    }

    static void checkBasicTypes(float x) {
        System.out.println("Type float: " + x);
    }

    static void checkBasicTypes(double x) {
        System.out.println("Type double: " + x);
    }

}

Output:

Type long: 5

The variable x is of type int, but the checkBasicTypes() method does not have an int parameter. When the program is running, it will find a method with a parameter type larger than the int type for calling, that is, the passed data type will be automatically promoted when the data type passed in is smaller than the parameter type. (int -> long)

Overriding#

Overriding generally occurs between parent and child classes, where the parent class and the child class have two methods with the same name and parameter list. Because they have the same method name, when the method is called, the method of the child class will override the same-named method of the parent class.

Here is an example of overriding:

public class Test {

    public static void main(String[] args) {
        Animal animal = new Dog();
        animal.say();
    }
}

class Animal {
    public void say() {
        System.out.println("I'm animal.");
    }
}

class Dog extends Animal {

    @Override
    public void say() {
        System.out.println("I'm Dog.");
    }

    public void eat() {
        System.out.println("Dog likes to eat meat.");
    }
}

Output:

I'm Dog.

In the above example, both the parent class and the child class define the say() method. In fact, the child class overrides the say() method of the parent class.

After overriding the method, when we call the say() method of the child class object, even though the type of the Dog object is Animal, Java will still call the say() method of Dog, because the method of the child class will override the same-named method of the parent class.

Principles of Overriding#

If you need to override a method, you need to satisfy the Liskov Substitution Principle:

  • The access permission of the subclass method must be greater than or equal to that of the superclass method.
    • For example, if the access modifier of the superclass method is protected, the access modifier of the subclass method can only be protected or public.
  • The return type of the subclass method must be the same as or a subtype of the return type of the superclass method.
    • For example, B extends A: the return type of the parent method is A, so the return type of the subclass method can be A or B.
  • The exception type thrown by the subclass method must be the same as or a subtype of the exception type thrown by the superclass.

@Override Annotation#

The @Override annotation is not a keyword in Java, but it can be used like a keyword. If this annotation is added to the overridden method, the compiler will help you check whether it meets the three restrictions mentioned above, and check whether this overridden method is legal. Sometimes it can also effectively prevent accidental overloading.

References#

Loading...
Ownership of this post data is guaranteed by blockchain and smart contracts to the creator alone.