简体   繁体   中英

Compile time polymorphism

I have a question about compile time polymorphism in java.

Is method overloading a way to achieve compile time polymorphism? If it is, is it the only way? Little example would help me a lot.

I searched in the web and different sources give different answers and its confusing. That is why I thought of asking it here.

Thanks in advance.

I found this external source . It makes the statement that there is no "compile time polymorphism". You probably mean "runtime polymorphism"?

Essentially, polymorphism refers to the feature that a method is not executed by a fixed method implementation that is defined at compile time, but rather there is a lookup at runtime which method implementation is chosen to execute the call.

For example, there is Object::equals in Java, which has an implementation in the "Object" class. If you create you own class that has its own implementation of the "equals" method, that implementation will be chosen when you compare instances, instead of the implementation defined in the "Object" class.

Polymorphism gets really handy when the complete list of implementations for a method is unknown, eg because you provide a library that is used in programs/other libraries that can declare their own (derived) classes that implement the method.

Consider this example

interface Animal {
  public void move(location);
}

Animal[] noahsArk = new Animal[...];
for (Animal animal : allAnimals) {
  move(arkLocation);
}

Since Dogs, Cats, Ants etc are all Animals, we can move(...) them all together, without worrying about the details of moving each one

In short, the compiler is aware about the static polymorphism because all the methods in same class are different even when they have the same name, the difference is because of their method signatures.

To execute a java program, ( java class), we need to 1st compile (using Javac the compiler ) it and 2nd run ( using java the Interpreter ).

Compile time vs Runtime

Compile time --- Compiler (javac) is aware, it knows during the Compilation time.

Runtime --- Java Interpretor ( java ) is aware but it is during the Runtime, and Runtime polymorphism happens between the Parent child relationship classes. The child provides the overriding of the method declared in the parent class.

Compile time vs Runtime polymorphism example:-

package com.deep.javazone.example2;
public interface Tax
{
    // Defining some default behaviour of tax calculation
    public  double calculateTax(double amount);
    // Used to calculate the tax for particular no of years
    public  double calculateTax(double amount, double years);
    // Used to calculate the tax for particular no of years excluding the the current year
    public  double calculateTax(double amount, double years, Boolean excludeCurrentYear);
}

////Sales Tax Implementation

package com.deep.javazone.example2;
public class SalesTax implements Tax{
        public  double calculateTax(double amount){
            double calculatedTax = 0.0;
            //Todo
            return calculatedTax;
        }
        public  double calculateTax(double amount, double years){
            double calculatedTax = 0.0;
            //Todo
            return calculatedTax;
        }
        public  double calculateTax(double amount, double years, Boolean excludeCurrentYear){
            double calculatedTax = 0.0;
            //Todo
            return calculatedTax;
        }
}

//// Service Tax implmentation

package com.deep.javazone.example2;
public class ServiceTax implements Tax{
        public  double calculateTax(double amount){
            double calculatedTax = 0.0;
            //Todo
            return calculatedTax;
        }
        public  double calculateTax(double amount, double years){
            double calculatedTax = 0.0;
            //Todo
            return calculatedTax;
        }
        public  double calculateTax(double amount, double years, Boolean excludeCurrentYear){
            double calculatedTax = 0.0;
            //Todo
            return calculatedTax;
        }
}

//// Tax Calculator

package com.deep.javazone.example2;
public class CalculateTax {
    public static void main(String[] args) {

        CalculateTax calculateTax = new CalculateTax();
        // Sales Tax
        Tax tax = new SalesTax();
        calculateTax.calculateTax(tax, 200000);
        calculateTax.calculateTax(tax, 2000000, 5);
        calculateTax.calculateTax(tax, 2000000, 5, false);

        //Service Tax
        tax = new ServiceTax();
        calculateTax.calculateTax(tax, 200000);
        calculateTax.calculateTax(tax, 2000000, 5);
        calculateTax.calculateTax(tax, 2000000, 5, false);  
    }

    public double calculateTax(Tax tax, double amount){
        return tax.calculateTax(amount);
    }
    public double calculateTax(Tax tax, double amount, double noOfYEars){
        return tax.calculateTax(amount, noOfYEars);
    }
    public double calculateTax(Tax tax, double amount, double noOfYEars, boolean currentYear){
        return tax.calculateTax(amount, noOfYEars, currentYear);
    }   
}

In the above example, when compilation of the CalculateTax class's main method happens, the compiler is very much sure and clear that which overloaded methods of class CalculateTax are being called as all the methods having same name but having different signatures ( method parameters).

But while compiling the other overloaded method's code, the compiler have no idea that later at runtime what kind of Tax reference will be passed in to the method parameters. For example the Tax is the interface and ServiceTax and SalesTax are it's implementation which provides the runtime polymorphism.

Hope I was able to answer your question. :)

Is method overloading a way to achieve compile time polymorphism? If it is, is it the only way? Little example would help me a lot.

The first answer is yes.Because before the program running, you know which method you will run by the type and number of parameter even though the two methods have same name.

//the example of code to show compile time poly
public class A{
public void fun(int a){
  //do something
}
public void fun(String a){
  //do something else
}
}

The second answer is No.Sometimes method override can be compile time polymorphism. example like:

public class Father(){
  public void say(){
    System.out.println("Father");
  }
}

public class Son extends Father{
  public void say(){
    System.out.println("Son");
  }
}

Now the compile time polymorphism:

public class Test{
  public static void main(String args[]){
    Father father=new Father();
    father.say();//You know it is father,right?
    Son son=new Son();
    son.say();//You know it is son,right?
  }
}

as a comparison:

public class Test2{
  public static void main(String args[]){
    Father father=new Son();//the reference of Father point to the object of 
//Son
    father.say();//only runtime we know which say() is running here
  }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM