重写、重载 和 可变参数

一、重写、重载 和 可变参数

1.1 重写方法的规则:

  • 参数列表必须完全与被重写的方法相同,否则不能称其为重写而是重载。
  • 返回的类型必须一直与被重写的方法的返回类型相同(相同或是其子类),否则不能称其为重写而是重载。
package base;

public class Test {

    public static void main(String[] args) {
        Parent person = new Children();
        person.getAge();
    }
}

class Parent {

    Object getAge() {
        System.out.println("parent...");
        return null;
    }
}

class Children extends Parent {
     //方法重写,返回值相同或是其子类
    @Override
    Integer getAge() {
        System.out.println("children...");
        return 0;
    }
}
  • 访问修饰符的限制一定要大于等于被重写方法的访问修饰符(public>=protected>=default) ;重写方法不能缩小访问权限;
    这里写图片描述
    如果访问权限比重写的权限小,则不能通过编译。

如果父类中有一个private方法,而子类有一个相同的方法,那么这个也不叫重写;两个方法可以同时存在。

这里写图片描述

  • 重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常。例如:父类的一个方法申明了一个检查异常IOException,在重写这个方法是就不能抛出Exception,只能抛出IOException的子类异常,可以抛出非检查异常。

1.2 而重载的规则:

  • 必须具有不同的参数列表;
  • 可以有相同的返回类型,只要参数列表不同就可以了;
  • 可以有不同的访问修饰符;
  • 可以抛出不同的异常;

用好重写和重载可以设计一个结构清晰而简洁的类,可以说重写和重载在编写代码过程中的作用非同一般.


1.3 可变参数

这里写图片描述

可变参数:适用于参数个数不确定,类型确定的情况,java把可变参数当做数组处理

注意:可变参数必须位于最后一项。因为参数个数不定,所以当其后边还有相同类型参数时,java无法区分传入的参数属于前一个可变参数还是后边的参数,所以只能让可变参数位于最后一项。


1.3.1 可变长参数的使用规则

  • 在调用方法的时候,如果能够和固定参数的方法匹配,也能够与可变长参数的方法匹配,则选择固定参数的方法
public class VarArgsTest {
public void print(String... args) {
        for (int i = 0; i < args.length; i++) {
            out.println(args[i]);
        }
    }
public void print(String test) {
        out.println("----------");
    }
public static void main(String[] args) {
        VarArgsTest test = new VarArgsTest();
        test.print("hello");
        test.print("hello", "alexia");
    }
}

优先匹配固定参数方法; 避免带有可变长参数的方法重载,编译器虽然知道怎么调用,但人容易陷入调用的陷阱及误区


  • 如果要调用的方法可以和两个可变参数匹配,则出现错误
public class VarArgsTest1 {
public void print(String... args) {
        for (int i = 0; i < args.length; i++) {
            out.println(args[i]);
        }
    }
public void print(String test,String...args ){
          out.println("----------");
    }
public static void main(String[] args) {
        VarArgsTest1 test = new VarArgsTest1();
        test.print("hello");
        test.print("hello", "alexia");
    }
}

对于上面的代码,main方法中的两个调用都不能编译通过,因为编译器不知道该选哪个方法调用


  • 一个方法只能有一个可变长参数,并且这个可变长参数必须是该方法的最后一个参
//以下两种方法定义都是错误的。

 public void test(String... strings,ArrayList list){

 }

 public void test(String... strings,ArrayList... list){


 }

  • 别让null值和空值威胁到变长方法
public class VarArgsTest1 {
public void print(String test, Integer... is) {

    }
public void print(String test,String...args ){

    }
public static void main(String[] args) {
        VarArgsTest1 test = new VarArgsTest1();
        test.print("hello");
        test.print("hello", null);
    }
}

两个调用编译都不通过:因为两个方法都匹配,编译器不知道选哪个,于是报错了,这里同时还有个非常不好的编码习惯,即调用者隐藏了实参类型,这是非常危险的,不仅仅调用者需要猜测该调用哪个方法,而且被调用者也可能产生内部逻辑混乱的情况


对于本例来说应该做如下修改

public static void main(String[] args) {
    VarArgsTest1 test = new VarArgsTest1();
    String[] strs = null;
    test.print("hello", strs);
}

查看下面打印结果:

public class VarArgsTest {
    public static void m1(String s, String... ss) {
        for (int i = 0; i < ss.length; i++) {
            System.out.println(ss[i]);
        }
    }
public static void main(String[] args) {
        m1("");
        m1("aaa");
        m1("aaa", "bbb");
    }
}

输出结果:

bbb

精准匹配优先。


参考

java中重载与重写的区别
java中可变长参数的使用及注意事项

猜你喜欢

转载自blog.csdn.net/qq_31156277/article/details/80759822