Java方法的重载与重写

192 阅读5分钟

1.方法重载

1.重载的含义

C ++同时支持方法重载和操作符重载,但是 Java 只支持方法重载

一个类中可以有多个方法具有相同的名字,但这些方法的参数必须不同,类似于类里可以有多个构造函数。参数不同是指满足下列之一:

  • 参数的个数不同。
  • 参数的个数相同,但参数列表中对应的某个参数的类型不同。
class People {

   float hello(int a,int b) {

      return a+b;

   }

   float hello(long a,int b) {//参数的类型不同

      return a-b;

   }

   double hello(int a,int b,int c) {//参数的个数不同

      return a*b*c;

   }

}
  • 方法的返回类型不影响重载
  • 重载与方法名无关
  • 在重载时,参数的类型可以是某个类
//Circle为声明的圆类,Tixing为梯形类

double computerArea(Circle c) {//重载

    double area=c.getArea();

    return area;

}

double computerArea(Tixing t) {//重载

    double area=t.getArea();

    return area;

}

2.避免重载出现歧义

方法重载时,对于没有明确给出对应类型的,会进行类型提升

class Demo{

   void disp(int a, double b){

        System.out.println("Method A");

   }

   void disp(int a, double b, double c){

        System.out.println("Method B");

   }

   public static void main(String args[]){

        Demo obj = new Demo();

        obj.disp(100, 20.67f);

   }

}

输出

Method A

虽然没有对应的float类型,但会提升后调用double类型的方法

类型提升表:

左侧的数据类型可以提升为右侧的任何数据类型。

byteshortintlong

shortintlong

intlongfloatdouble

floatdouble

longfloatdouble

但有时候类型提升会产生歧义

class Dog {

    void cry(double m,int n){

        System.out.println("小狗");

     }

     //重载,类型不同

    void cry(int n,double m){

        System.out.println("small dog");

     }

 }

对于上面的方法

Dog.cry(3.4,3);

会输出“小狗”

Dog.cry(3,3.4);

会输出“small dog”

但是如果是:

Dog.cry(3,3);

无法通过编译,因为不知道执行重载方法的哪一个(歧义调用),或者说没有对应参数类型的方法可以调用;

3.静态多态与动态多态

静态多态性指的是程序在编译时,系统就能决定调用哪个函数。静态多态也称为编译时绑定或早期绑定。如重载。

动态多态性指在运行中才能动态确定操作指针所指的对象,如重写。因为重写的方法调用在运行时得到解析。

//静态多态

class Calculation {

    void sum(int a, int b) {//A

        System.out.println(a + b);

    }



    void sum(int a, int b, int c) {//B

        System.out.println(a + b + c);

    }



    public static void main(String args[]) {

        Calculation obj = new Calculation();

        obj.sum(10, 10, 10);  // 30 编译时确定调用B

        obj.sum(20, 20);     //40  编译时确定调用A

    }

} 
//动态多态

class Animal {

    public void move() {

        System.out.println("Animals can move");

    }

}



class Dog extends Animal {

    public void move() {

        System.out.println("Dogs can walk and run");

    }

}



public class TestDog {

    public static void main(String args[]) {

        Animal a = new Animal(); // Animal reference and object

        Animal b = new Dog(); // Animal reference but Dog object

        a.move();//output: Animals can move

        b.move();//output:Dogs can walk and run运行时知道调用重写的方法

    }

}

2.方法重写

如果子类可以继承父类的某个方法,那么子类就有权利重写这个方法。所谓方法重写,是指子类中定义一个方法,这个方法的类型和父类的方法的类型一致或者是父类的方法的类型的子类型(所谓子类型,是指如果父类的方法的类型是“类”,那么允许子类的重写方法的类型是“子类”),并且这个方法的名字、参数个数、参数的类型和父类的方法完全相同。子类如此定义的方法称作子类重写的方法。

2.1重写的意义

如果子类重写某方法,那么会隐藏从父类继承的方法,子类就可以拥有符合自身状态和行为的方法。

如果B继承A,C继承B,B重写了A的某个方法,但C没重写该方法,那么C继承来的是B重写的方法。

class Animal {

    public void move() {

        System.out.println("Animals can move");

    }

}



class Dog extends Animal {

    public void move() {

        System.out.println("Dogs can walk and run");

    }

}



class q extends Dog {



}



public class test {

    public static void main(String args[]) {

        q qq = new q();

        qq.move();

    }

}

2.2调用权限

重写方法既可以操作继承的成员变量、调用继承的方法,也可以操作子类新声明的成员变量、调用新定义的其他方法,但无法操作被子类隐藏的成员变量和方法。如果子类想使用被隐藏的方法或成员变量,必须使用关键字super 。

重写方法时不可以降低方法的访问权限,但可以提高提高权限。

2.3案例

class Human{//父类

   protected void eat()

   {

      System.out.println("Human is eating");

   }

}

class Boy extends Human{//子类

   public void eat(){//重写eat方法,访问权限提升

      System.out.println("Boy is eating");

   }

   public static void main( String args[]) {

      Boy obj = new Boy();

      obj.eat();

   }

}

输出

Boy is eating

2.4不能重写的方法

final、static 的方法不能被重写。

final无法被继承,因此不能重写

静态成员(方法或属性)是类的成员存放在堆中,类可以直接调用(是属于类的静态成员,当然对象也可以调用,只是说你可以使用而已);实例成员是对象的成员,存放在堆中,只能被对象调用。

重写的目的在于根据创造对象的所属类型不同而表现出多态。因为静态方法无需创建对象即可使用。没有对象,重写所需要的“对象所属类型” 这一要素不存在,因此无法被重写。但可以继承,可以通过父类的类名调用或者自己的类名。

    class Animal {

    protected static void move() {

        System.out.println("Animals can move");

    }

}

class Dog extends Animal {

}

public class test {

    public static void main(String args[]) {

        //Animal qq = new Animal();

        Dog.move();

        Animal.move();

    }

}

子类虽然能构造和父类一样的静态方法,但不是重写,只是对父类的隐藏。



class Animal {

    public static void move() {

        System.out.println("Animals can move");

    }

}



class Dog extends Animal {

    public static void move() {

        System.out.println("Dog can move");

    }



    public void Yachting() {

        super.move();

    }

}



public class test {

    public static void main(String args[]) {

        Dog.move();//子类静态方法

        Animal.move();//父类静态方法

        Dog a = new Dog();

        a.Yachting();//super调用隐藏的方法

    }

}