1、方法的重写(Override)(方法覆盖)
(1)重写介绍:
java SE5增加@Override注解,并不是关键字,覆写某个方法时,添加此注解。@Override可以防止在不想重载时而意外地进行重载。
- 父类与之类之间的多态性,对父类的函数进行重新定义。同方法名和同参数;
- 子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数列表,则新方法将覆盖原有的方法,若需要父类中原有的方法,使用super关键字;
- 子类函数的访问修饰符不能小于父类的;(父类为public,则子类不能为protected或者private等,只能是public的)
- 子类抛出异常小于等于父类方法抛出异常;
- 重写Override,运行时,方法重写(子类继承父类并重写方法)以及对象造型(父引用子类型对象),父子类的多态性表现,是动态分派,指令invokevirtual,在运行期间根据常量池中的类方法的符号引用解析到实际的类型上;
(2)两同两小一大原则:
两同:方法名相同,参数类型相同
两小:子类返回类型小于等于父类方法返回类型,
子类抛出异常小于等于父类方法抛出异常,
一大:子类访问权限大于等于父类方法访问权限。
- 参数列表必须完全与被重写方法的相同;
- 返回类型必须完全与被重写方法的返回类型相同;(备注:这条信息是标准的重写方法的规则,但是在java 1.5 版本之前返回类型必须一样,1.5(包含)j 版本之后ava放宽了限制,返回类型必须小于或者等于父类方法的返回类型 )。才有了子类返回类型小于等于父类方法返回类型。在java里面这个怎么样都是正确的,谨记。
- 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类的一个方法被声明为public,那么在子类中重写该方法就不能声明为protected。否则会有以下信息:Cannot reduce the visibility of the inherited method from Base
- 父类的成员方法只能被它的子类重写。
- 声明为final的方法不能被重写。
- 声明为static的方法不能被重写,但是能够被再次声明。(static和final的都不能被重写)
- 子类和父类在同一个包中,那么子类可以重写父类所有方法,除了声明为private和final的方法。
- 子类和父类不在同一个包中,那么子类只能够重写父类的声明为public和protected的非final方法。
- 重写的方法能够抛出任何非强制异常,无论被重写的方法是否抛出异常。但是,重写的方法不能抛出新的强制性异常,或者不能抛出比被重写方法声明的更广泛的强制性异常,反之则可以。
- 构造方法不能被重写。(构造方法属于static的)
- 如果不能继承一个方法,则不能重写这个方法。
2、方法的重载overload
(1)重载介绍
- 方法名一样,但参数类型和个数一样,返回值类型可以相同也可以不同,无法以返回类型作为重载函数的区分标准;
- 方法重载就是在类中创建多个方法,方法名相同,参数列表不同,调用方法时通过传递给它们的不同参数个数和参数类型来决定具体使用哪个方法,体现多态性;
- 方法重载是让类以统一的方法处理不同类型数据(同方法名,不同参数列表)的一种手段;
- 重载overload,编译时,同一个类中,同名方法有不同参数列表(个数、类型),是一个类中多态性的表现,是静态分派,在编译期,通过静态类型而不是实际类型作为判定依据(静态方法也可以重载);
(2)构造方法的重载
【构造方法的重载】:只需要看参数即可,如果想在一个构造方法中调用另一个构造方法,那么可以使用this()的方法调用,this()括号中的参数表示目标构造方法的参数,this()必须要作为构造方法的第一跳语句,换句话说,this()之前不能有任何可执行的代码。
3、重写和重载:(多态)
底层实现(静态分派和动态分派)
- 重载overload,编译时,同一个类中,同名方法有不同参数列表(个数、类型),是一个类中多态性的表现,是静态分派,在编译期,通过静态类型而不是实际类型作为判定依据(静态方法也可以重载);
- 重写override,运行时,方法重写(子类继承父类并重写方法)以及对象造型(父引用子类型对象),父子类的多态性表现,是动态分派,指令invokevirtual,在运行期间根据常量池中的类方法的符号引用解析到实际的类型上;
多态
1.多态性是面向对象编程的一种特性,和方法无关;
2.同样的一个方法能够根据输入数据的不同,做出不同的处理,即方法的重载——有不同的参数列表(静态多态性);
3.当子类继承自父类的相同方法,输入数据一样,但要做出有别于父类的响应时,你就要覆盖父类方法, 即在子类中重写该方法——相同参数,不同实现(动态多态性);
4、区别总结:
单词:重载overload,重写loverride;
形式:重载,方法名相同,参数列表不同(个数、类型、顺序);重写,方法名、返回值、参数列表都相同;
范围:重载,是编译时的静态分派,同一个类中;重写,运行时动态分派,发生在继承的父子类中;
权限:重载,没有权限限制;重写,子类的覆写的方法权限不能比父类的访问权限小;