【重写意义】
子类需要父类中功能时,而功能主体又持有内容同时时,可以复写父类中的方法,即调用了父类沿袭的功能,又定义了子类持有的功能
重写规则:
方法的声明,权限修饰符,返回值类型 方法名(形参列表) throws 异常的类型{ //方法体 }
// 约定俗称: 子类中的叫重写的方法,父类中的叫被重写的方法 1. 子类重写的方法 方法名 和 形参列表 与父类的一样 2.子类重写的方法的权限修饰符不小于父类被重写的方法的权限修饰符 > 特殊情况 子类不能重写父类中的private方法 3.返回值类型: >父类被重写的方法的返回值类型是void,则子类重写的方法的返回值也只能是void > 父类被重写的方法的返回类型是A类型,则子类重写的方法的返回值类型可以是A类,或者是A类的子类 4.子类重写的方法抛出的异常类型,不大于父类被重写的抛出的异常类型5.子类和父类的同名同参数的方法要不都声明为static,要么都声明为static(静态都不是重写)
【重写练习】
1.如果现在父类一个方法定义成private访问权限,在子类中将次方法声明为default访问权限,那么这样还叫重写吗?(no)
2.修改练习,1.3中定义的类Kids,在Kids重新定义employeed()方法,覆盖父类ManKind中定义的
employeed()方法,输出“Kids should study and no job”
[kids类]
package Jc.exer;
public class Kids extends MandKind{ // 子类继承父类 MandKind
//成员变量
private int yearsOld;
// 构造器
public Kids(){
}
public Kids(int yearsOld) {
this.yearsOld = yearsOld;
}
//子类特用方法
public void printAge(){
// 打印 yearsOld的值
System.out.println("I am "+yearsOld+"years old.");
}
//set get 方法
public int getYearsOld() {
return yearsOld;
}
public void setYearsOld(int yearsOld) {
this.yearsOld = yearsOld;
}
// 覆盖父类中的方法 employeed()方法,
public void employeed(){
System.out.println("Kids should study and no job");
}
}
[manKind]父类
package Jc.exer;
public class MandKind {
//成员变量 int sex 和inti salary;
// 方法 void manOrWoman: 根据sex的值显示:.......
//方法 void employeed(): 根据salary的值显示"no job"
private int sex ; // 男1 女 0
private int salary; //薪水
//构造器
public MandKind(){
}
public MandKind(int sex, int salary) {
this.sex = sex;
this.salary = salary;
}
// 公共的方法
public void manOrWoman(){ //调方法返回 是 男 还是女
//根据 sex 的值显示 "man" (sex ==1) 或者"woman"(sex==0)
if(sex ==1){
System.out.println("man");
}else if(sex ==0){
System.out.println("woman");
}
}
public void employeed(){ //调用方法,看是否有工作 0无 1有
//根据 salary 的值显示 "no job" (salry==0)或者 "job (salry!=0)"
// if(salary ==0){
// System.out.println("no job");
// }else{
// System.out.println("job");
// }
String jobInfo = salary == 0 ? "no job" : "job";
System.out.println(jobInfo);
}
//两个属性的get set 方法
public void setSex(int sex){
this.sex=sex;
}
public int getSex(){
return sex;
}
public void setSalary(int salary){
this.salary=salary;
}
public int getSalary(){
return salary;
}
}
[测试类] 控制台输出结果
package Jc.exer;
public class KidTest { //测试类
public static void main(String[] args) {
//实例化main 放中实例化Kids的对象 someKid,用改对象访问其父类的成员变量及方法
Kids somKid = new Kids(12);//带参数的 12岁
somKid.printAge();
somKid.setSalary(0);
somKid.setSex(1);
System.out.println(somKid.getSalary());
System.out.println(somKid.getSex());
somKid.manOrWoman();
somKid.employeed();
}
}
[结果]
3,。练习: 圆类求面积方法,子类圆柱重写父类方法,求圆柱的表面积。
[父类圆]
// 该类的方法 计算圆的面积
public double findArea(){
return Math.PI*radius*radius;
}
[子类圆柱]
子类这个方法重写了父类findArea方法,而在方法体中又需要调用父类的圆的面积,即为圆柱的底面积,可是 return super.findArea()*2+2*Math.PI*getRadius()*getLength(); 递归了吧,一直自己调用自己,怎么调用父类中的findArea()方法呢,用super,super指向当前对象的父类型特征。
// 求圆柱的表面积
public double findArea(){
//递归调用自己调用自己,问题来了怎么调用父类中的findArea呢,而不是自己(重写后的)
return super.findArea()*2+2*Math.PI*getRadius()*getLength();
// return Math.PI*getRadius()*getRadius()*2+2*Math.PI*getRadius()*getLength();
}
其实这里会有这样的疑惑,为什么要重写,不重写的话,直接 在方法中调用findArea()方法,(首先求圆柱的表面积的方法名不是findArea) return super.findArea()*2+2*Math.PI*getRadius()*getLength(); java概念太多了啊
问题来了,要使用到super关键字
说明:
- 重写中super方法使用 :
- 1.super是当前对象的父类对象的默认引用, '父类'
- 2.super必须出现在子类中(方法或构造函数中)
- 3.super无法访问private成员属性和方法
【结果】
4.super简单使用练习
举个例子: 子类中调用重写的的变量,又可以使用super调用被重写变量(父类变量)
public class AA {
String S ="A"; //缺省
}
class B extends AA{
String S ="B"; // 重写父类的变量
public void getName(){
System.out.println("子类"+S);
System.out.println("父类"+super.S); // 调用的是 父类被 重写 的 变量(父类)
}
// 主main方法,测试用
public static void main (String[] args){
B b = new B();
b.getName();
}
}
4.2子类重写方法中 调用父类被重写方法
package Super;
public class A {
public void getName(){
System.out.println("父类方法");
}
}
class B extends A{
@Override
public void getName(){
// System.out.println("子类方法");
super.getName(); //自己调用自己,不加super
}
public static void main (String[] args){
B b = new B();
b.getName();
}
}
【结果】
错误写法
@Override
public void getName(){
// System.out.println("子类方法");
getName(); //自己调用自己,不加super
}
【结果】
学习记录