编译时间多态

时间:2017-04-14 17:58:52

标签: java polymorphism

我对java中的编译时多态性有疑问。

方法重载是一种实现编译时多态的方法吗?如果是的话,这是唯一的方法吗?很少的例子会对我有所帮助。

我在网上搜索,不同的来源给出了不同的答案和令人困惑的。这就是为什么我想在这里问它。

提前致谢。

4 个答案:

答案 0 :(得分:5)

我发现了external source。它声明没有“编译时多态”。你可能的意思是“运行时多态”?

本质上,多态性指的是一个方法不是由在编译时定义的固定方法实现执行的特性,而是在运行时查找选择哪个方法实现来执行调用。

例如,Java中有Object :: equals,它在“Object”类中有一个实现。如果您创建自己的具有自己的“equals”方法实现的类,则在比较实例时将选择该实现,而不是在“Object”类中定义的实现。

当方法的完整实现列表未知时,多态性变得非常方便,例如:因为你提供了一个在程序/其他库中使用的库,可以声明它们自己的(派生的)实现该方法的类。

答案 1 :(得分:3)

考虑这个例子

interface Animal {
  public void move(location);
}

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

由于狗,猫,蚂蚁等都是动物,我们可以将它们一起移动(...),而不必担心移动每个动物的细节

答案 2 :(得分:3)

简而言之,编译器知道静态多态,因为同一个类中的所有方法即使它们具有相同的名称也是不同的,区别在于它们的方法签名。

要执行java程序(java类),我们需要先编译(使用Javac编译器)和第二次运行(使用java解释器)。

编译时间与运行时间

编译时间---编译器(javac)知道,它在编译期间知道。

运行时--- Java解释器(java)知道但它在运行时期间,并且运行时多态性发生在父子关系类之间。子级提供了在父类中声明的方法的覆盖。

编译时间与运行时多态性示例: -

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);
}

////销售税实施

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;
        }
}

////服务税征收

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;
        }
}

////税务计算器

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);
    }   
}

在上面的示例中,当编译CalculateTax类的main方法时,编译器非常确定并清楚调用类CalculateTax的哪些重载方法,因为所有方法具有相同的名称但具有不同的签名(方法参数) )。

但是在编译其他重载方法的代码时,编译器不知道以后在运行时将哪种Tax引用传递给方法参数。例如,Tax是接口,ServiceTax和SalesTax是它的实现,它提供了运行时多态性。

希望我能回答你的问题。 :)

答案 3 :(得分:2)

  

方法重载是一种实现编译时多态的方法吗?如果是的话,这是唯一的方法吗?很少的例子会对我有所帮助。

第一个答案是肯定的。因为在程序运行之前,你知道参数的类型和数量将运行哪种方法,即使这两种方法具有相同的名称。

//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
}
}

第二个答案是No.Sometimes方法覆盖可以编译时多态。 例如:

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

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

现在编译时多态:

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?
  }
}

作为比较:

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
  }
}