zoukankan      html  css  js  c++  java
  • java 覆盖

    作者:又见那斯
    java中覆盖基于面向对象三大特征之:继承,同时又和另一特征:多态有重要的联系,本文中讨论的有关java中覆盖的一些知识,其实在写代码的时候或许不会用到,不过知道的话总会有用处。如有错误,欢迎批评指正。

    1,基本的方法覆盖
    java中,覆盖是指在子类中定义与父类同名且参数类型和个数都相同的方法。 如:
    public class A{
    public void test(int i){
    System.out.println(“class A”);
    }
    }
    public class B extends A{
    public void test(int i){
    System.out.println(“class B”);
    }
    }

    子类B的test方法覆盖了父类A的test方法,因为两个方法的名字和参数都完全一样,构成覆盖.这么做的意义当然是为了在子类B中提供不同的test实现,覆盖也即是多态的基础,可以这么说,有方法覆盖就可以多态调用方法,下面的覆盖测试都是通过多态调用来测试的,如
    A a=new B();则a.test(1)的结果是控制台输出:class B

    2,参数相关
    覆盖对于参数的有求是类型和参数个数一样,不过有两点需要注意,看有如下代码:
    public class A{
    public void test1(Object obj){}
    public void test2(String…str){}
    }
    public class B extends A{
    public void test1(String obj){}
    public void test2(String str){}
    }
    请问B类中哪些方法是覆盖了父类的方法?
    答案是B类中两个方法都没产生覆盖,

    分析test1,父类A中要求是Object类型,而子类B中是String 类行,大家知道一个String也是一个Object,但是事实上没有产生覆盖
    它们还是被认为不同的类型,不过有时能产生与覆盖相同的效果(当然这也只限于B类,不适合A类的其他子类).

    分析test2,父类A中的test2采用了1.5新特性:可变长参数,在传参数这点上我认为只要把握一点,就是类型完全相同,才是覆盖。另外大家知道,可变长参数str的类型其实是String[],那么很明显String和String[]是完全不同的类型,当然不会产生覆盖。
    调用测试:
    A a=new B();
    a.test1(“hello”);—-调用B类的test1()
    a.test1(new Integer(1));—–调用A类的test1()
    a.test2(“hello”);——调用A类的test2()
    ((B)a).test2(“hello”);—-调用B类的test2()

    3,返回类型相关
    大家都知道,方法覆盖是不能根据返回类型来判断的,比如:
    public class A{
    public int test(){}
    }
    public class B extends A{
    public String test(){}
    }
    编译将不通过,因为不能通过返回类型来区别两个方法,所以就会产生重复定义的错误,即不构成重载,但也不是覆盖(下面将具体说明)。可以这么认为,编译器不允许有除重载和覆盖之外的同名和同参数的方法存在。

    如果子类中方法的方法名,参数,和返回类型都完全相同,那么显而易见,构成覆盖,然而java中还有一种可以返回类型不同,又不会出错的情况就是:级联返回,
    如:
    public class A{
    public Object test(){}
    }
    public class B extends A{
    public String test(){}
    }
    这种情况是允许的,A类中test方法返回Object类型,B类中返回String,String类是Object类的子类。返回类型是父类相应方法的子类,也构成覆盖。当然这种情况更多的是出现用到泛型的时候,比如:
    public class A{
    public T test(){}
    }
    public class B extends A{
    public String test(){}
    }
    这也一样的道理,也是方法的覆盖.
    测试:
    A a=new B();
    a.test();—–多态调用B中的test方法

    4,修饰符相关
    关于修饰符,对覆盖也是有约束的,比如private方法吧能被覆盖,final方法不能被覆盖,继承时一定要覆盖父类的abstract方法。这里面也要注意几点:
    如:
    (1) private
    public class A{
    private void test(){}
    public static void main(String[] args){
    A a=new B();
    a.test();//没有覆盖就不会多态调用,此处调用的是A类的test方法
    }
    }
    public class B extends A{
    public void test(){}
    }
    (2)final和abstract修饰符不能连,想想就知道,final就是不让覆盖,abstract是必须覆盖,如一起,岂不矛盾。
    (3)子类中覆盖的方法的访问权限(可见度)不能比父类低,如:
    public class A{
    public void test(){}
    }
    public class B extends(){
    protected void test(){}//编译出错
    }
    符:对synchronized关键字没有要求

    5,异常相关
    要求:覆盖时,子类中方法不能抛出比父类中相应方法更广泛的未检查异常。
    如:
    public class A{
    public void test() throws FileNotFoundException{}
    }
    public class B extends A{
    public void test() throws IOException{}/编译出错,IOException比FileNotFoundException范围广/
    }
    public class C extends A{
    public void test() throws RuntimeException{}//可以增抛运行时异常
    }

    6,静态方法相关
    要点:静态方法不能被覆盖,不过也要注意:
    public class A{
    public static void test1(){}
    }
    public class B extends A{
    // public void test(){}//编译出错,不允许这样
    public static void test(){}/可以“静态覆盖”(没这个词,只为说明问题)/
    }
    public class C extends A{}
    调用测试:
    A a=new B();
    B b=new B();
    a.test();—-调用A类的test()
    b.test();—-调用B类的test()
    A.test();—-显然的是调用A类的test();
    B.test();—-调用的是B类的test();
    C.test();—-还可以这么用?C类没有test()方法,但是可以这么用,调用的是A类的test(),B类中因为自己定义了test()方法,所以产生了覆盖的效果,所以”静态覆盖”还真存在。

    7,属性相关
    要点:类的属性是可以覆盖,但此时覆盖的同时没有多态。如
    public class A{
    public int i=1;
    public void test(){}
    }
    public class B extends A{
    public int i=2;
    public void test(){}
    }
    测试:
    A a=new B();
    (a.i==1)=true—-即a.i是指在父类A中定义的i,不存在多态
    a.test();——-调用子类B中的test(),多态

    8,构造方法相关
    要点:构造方法不存在覆盖一说,但可以重载。

  • 相关阅读:
    大二第二学期周学习进度总结(七)
    java课程之团队开发冲刺阶段1.1
    Java课程之团队开发(NABCD需求分析)
    大二第二学期周学习进度总结(六)
    Java课程之团队开发(团队介绍)
    大二第二学期周学习进度总结(五)
    模拟退火 费马点求解
    三分 传送带
    2357数
    B监狱 noip 模拟 7.29(区间DP)
  • 原文地址:https://www.cnblogs.com/luckycode/p/5255649.html
Copyright © 2011-2022 走看看