【哈工大软件构造】特殊多态(方法重载)

特殊多态(Ad hoc polymorphism

一个特殊多态的例子

定义:一个方法可以有多个同名的实现,即方法重载

当一个函数适用于多种不同的类型时,就会出现特殊多态,例如:

public class OverloadExample{
    public static void main(String[] args){
        System.out.println(2,3);
        System.out.println("A","B");
        System.out.println("C","D","E");
    }
    public static String add(String a, String b){
        return a.concat(b);
    }
    public static String add(String a, String b, String c){
        return a.concat(b).concat(c);
    }
    public static int add(int a, int b){
        return a + b;
    }
}

重载使得多种不同的方法有了同样的名字,但有不同的参数列表或者返回值类型。

作用:方便客户端调用,客户端可以用不同的参数列表调用同样的函数。

重载方法属于静态多态,它会根据参数列表进行静态匹配,在调用位置进行静态类型检查,在编译时具体决定执行什么方法(与之相反,方法重写需要在运行时进行动态检查)。

方法重载的规则

  1. 可以定义相同/不同的参数列表。
  2. 可以定义相同/不同的返回值类型。
  3. 可以定义相同/不同的访问权限。
  4. 可以定义相同/不同的异常。
  5. 一个方法可以在同一个类中重载,也可以在子类中重载。

方法重载的进一步讨论

我们定义若干动物类如下:

class Animal{
    public void eat(){}
}
class Horse extends Animal{
    public void eat(String food){}
}
public class UseAnimals{
    public void doStuff(Animal a){
        System.out.println("Animal");
    }
public void doStuff(Horse a){
        System.out.println("Horse");
    }
    
}

注意:这里子类和父类的eat方法之间是重载的关系,因为它们的方法签名不同。

我们定义测试类如下:

public class TestUseAnimals{
    public static void main(String[] args){
        UseAnimals ua = new UseAnimals();
        
        Animal animalobj = new Animal();
        Horse horseobj = new Horse();
        Animal animalRefToHorse = new Horse();
        
        ua.doStuff(animalobj);
        ua.doStuff(horseobj);
        ua.doStuff(animalRefToHorse);
    }
}

 运行结果如下:

特别注意第三个,方法重载匹配方法签名时按照其声明类型为准。 

我们添加对eat的具体实现:

class Animal{
    public void eat(){
        System.out.println("Animal eat nothing");
    }
}
class Horse extends Animal{
    public void eat(String food){
        System.out.println("Horse eat"+food);
    }
    public void eat(){
        System.out.println("Horse eat grass");
    }
}
public class UseAnimals{
    public void doStuff(Animal a){
        System.out.println("Animal");
    }
public void doStuff(Horse a){
        System.out.println("Horse");
    }
    
}

 改写测试代码:

public class TestUseAnimals{
    public static void main(String[] args){
        Animal animalobj = new Animal();
        Horse horseobj = new Horse();
        Animal animalRefToHorse = new Horse();
        
       animalobj.eat();//1
       horseobj.eat();//2
       animalRefToHorse.eat();//3
       animalobj.eat("APPLE");//4
       horseobj.eat("BANANA");//5
       animalRefToHorse.eat("BANANA");//6
    }
}

该代码不能运行,因而我们将逐一分析各个语句的执行。

语句1将直接调用Animal类中的eat方法,输出Animal eat nothing。

语句2使用了方法重写,将会使用Horse类中重写的eat方法。

语句3将调用Horse类中重写的方法,在静态检查的过程中,程序会检查Animal中是否有eat方法,而在运行时,程序会选择执行Horse中的eat方法。

语句4将会报错,因为静态检查时发现animal中不存在eat(String xxx)的方法。

语句5将会输出Horse eat BANANA

语句6将报编译时错误,因为静态检查时发现animal中不存在eat(String xxx)的方法,注意与语句3进行比较。

重载与重写的区别

  1. 重写时子类与父类具有相同的签名。
  2. 签名不同时为重载。
  3. 子类重载了父类的方法后,子类仍然继承了父类的方法。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值