Java基础之方法重写详解
一、java方法重写
方法的重写是子类根据需求对父类继承的方法进行重新的编写,在重写时,可以使用super方法的方式来保留父类中的方法,注意:构造方法不可以被重写。
创建一个人类,属性包括姓名 性别 年龄 行为方法是输出信息
二、super关键字
方法重写时要在子类中定义一个和父类相同名称的方法,并采用super关键字super.方法名();
,这样就实现了方法的重写
package cn.zhz.Kind.dh; public class Person1 { public String sex; public String name; public int age; public void showInfo() { System.out.println("姓名:" + name + "年龄:" + age + "性别:" + sex); } }
创建一个学生类,属性包括学号 学科,行为方法是输出信息
package cn.zhz.Kind.dh; public class Student1 extends Person1{ public int stuId; public String stuSubject; public void showInfo(){ super.showInfo(); System.out.println("学号:"+ stuId+ "学科:"+ stuSubject); } }
创建学生类的一个实例,进行赋值操作,赋值后输出
package cn.zhz.Case.dh; import cn.zhz.Kind.dh.Student1; public class Student1Test { public static void main(String[] args) { Student1 student1 = new Student1(); student1.stuId = 1; student1.name = "张三"; student1.age = 18; student1.sex = "男"; student1.stuSubject = "物理"; student1.showInfo(); } }
2.1 super关键字的介绍
super可以应用在子类访问父类成员中,比如说:
访问父类的属性
super.print();
注意是非private的方法
访问父类的方法super.name;
访问父类的构造方法super();
package cn.zhz.Inherit.dh; public class Pet { private String name = "无名氏"; private int health = 100; private int love = 0; public int age = 1; public Pet() { System.out.println("父类无参构造方法"); } public Pet(String name) { this.name = name; } public Pet(String name, int health, int love) { //this可以调用本类的构造方法,且在第一行 //this(name); this.name = name; this.health = health; this.love = love; System.out.println("父类带参构造方法"); } public void setAge(int age) { this.age = age; } public int getAge() { return age; } public void setHealth(int health) { if (health < 0 || health > 100) { System.out.println("宠物的健康值在0-100之间"); this.health = 60; return; } this.health = health; } public int getHealth() { return this.health; } public void setName(String name) { this.name = name; } public String getName() { return this.name; } public void setLove(int love) { if (love < 0 || love > 100) { System.out.println("宠物的亲密度只能在0-100之间"); this.love = 60; return; } this.love = love; } public int getLove() { return this.love; } //输出宠物的信息 public void print() { System.out.println("宠物的自白:\n我的名字叫" + this.name + "健康值是" + this.health + "和主人的亲密度是:" + this.love); } }
package cn.zhz.Inherit.dh; public class Dog extends Pet { private String strain = "聪明的拉布拉多犬"; public Dog() { System.out.println("子类狗狗的无参构造方法"); } public Dog(String name, int health, int love, String strain) { //通过super调用父类的构造方法,必须是第一句 //super(); super(name, health, love); this.strain = strain; System.out.println("狗狗的带参构造方法"); } public void setStrain(String strain) { this.strain = strain; } public String getStrain() { return this.strain; } public void print() { //调用父类的非private的print()方法 super.print(); System.out.println("我是一只" + this.strain); } public void m1() { //super不可以调用父类的private属性 // System.out.println(super.name); System.out.println(super.age); } }
在使用super关键字来访问父类的成员时,使用super关键字,super代表的是父类的对象,super只可以出现在子类的方法和构造方法中,使用super调用构造方法时,只可以是第一句,super不可以访问父类的private成员。
2.2 super关键字的使用
当子类中的方法重写了父类的方法,或者是在子类中定义了和父类的同名称的成员变量,使用super关键字可以使被屏蔽的成员可见。.
package cn.zhz.Inherit.dh; public class Pet { private String name = "无名氏"; private int health = 100; private int love = 0; public int age = 1; public Pet() { System.out.println("父类无参构造方法"); } public Pet(String name) { this.name = name; } public Pet(String name, int health, int love) { //this可以调用本类的构造方法,且在第一行 //this(name); this.name = name; this.health = health; this.love = love; System.out.println("父类带参构造方法"); } public void setAge(int age) { this.age = age; } public int getAge() { return age; } public void setHealth(int health) { if (health < 0 || health > 100) { System.out.println("宠物的健康值在0-100之间"); this.health = 60; return; } this.health = health; } public int getHealth() { return this.health; } public void setName(String name) { this.name = name; } public String getName() { return this.name; } public void setLove(int love) { if (love < 0 || love > 100) { System.out.println("宠物的亲密度只能在0-100之间"); this.love = 60; return; } this.love = love; } public int getLove() { return this.love; } //输出宠物的信息 public void print() { System.out.println("宠物的自白:\n我的名字叫" + this.name + "健康值是" + this.health + "和主人的亲密度是:" + this.love); } }
子类和父类中同时定义了一个age属性,子类调用这个age属性时先会在本类中找,这时可以使用super关键字代表父类,用super.属性
的方式调用父类中的age属性
package cn.zhz.Inherit.dh; public class Dog extends Pet { private String strain = "聪明的拉布拉多犬"; private int age = 10; public Dog() { System.out.println("子类狗狗的无参构造方法"); } public Dog(String name, int health, int love, String strain) { //通过super调用父类的构造方法,必须是第一句 //super(); super(name, health, love); this.strain = strain; System.out.println("狗狗的带参构造方法"); } public void setStrain(String strain) { this.strain = strain; } public String getStrain() { return this.strain; } public void print() { //调用父类的非private的print()方法 super.print(); System.out.println("我是一只" + this.strain); } public void m1() { //super不可以调用父类的private属性 // System.out.println(super.name); System.out.println(super.age); } public void m2() { //子类会覆盖服了诶的同名成员 System.out.println(this.age); //可以使用super关键字调用父类被子类覆盖的成员 System.out.println(super.age); } }
super和this的区别
区别 | this | super |
访问属性 | 访问本类的属性,如果没有则从父类中找 | 访问父类中的属性 |
访问方法 | 访问本类方法,如果没有从父类中找 | 访问父类的方法 |
访问构造方法 | 调用本类的构造方法,方法构造方法的首行 | 调用父类的构造方法,放在子类的构造方法的首行 |
总结的来说是this代表的是本类,而super代表的是父类
因为super代表的是父类,那么如果声明了多个类时,子类中如果要访问父类的父类的成员,难道要使用的是super.super.
的方式吗?
package cn.zhz.Kind; //爷爷类 public class Animal { private int age; private String sex; public int getAge() { return age; } public void setAge(int age) { this.age = age; } public String getSex() { return sex; } public void setSex(String sex) { this.sex = sex; } public void print() { System.out.println("爷爷类下的方法"); } }
package cn.zhz.Kind; public class Person extends Animal { public String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }
package cn.zhz.Kind; //孙子类 public class Student extends Person { private String sid; public String getSid() { return sid; } public void setSid(String sid) { this.sid = sid; } @Override public void print() { //访问父类的父类的成员,不可以使用super.super.的方法,可以直接使用super.print();来进行调用 super.print(); System.out.println("这个是孙子类下的方法"); } }
package cn.zhz.Instance; import cn.zhz.Kind.Student; public class StudentTest { public static void main(String[] args) { Student student = new Student(); student.print(); } }
Student孙子类调用Animal爷爷类时也是通过super.成员
的方式来调用,这是因为java是只支持单根继承的,一个类只可以有一个直接父类,但是一个类可以有多个的间接父类
三、继承下的构造方法的调用规则
package cn.zhz.Kind; public class Car { private int site = 4; Car(){ System.out.println("载客量是"+site+"人"); } public void setSite(int site){ this.site = site; } public void print(){ System.out.println("载客量是"+site+"人"); } }
package cn.zhz.Kind; public class Bus extends Car{ public Bus(int site){ setSite(site); } }
package cn.zhz.Instance; import cn.zhz.Kind.Bus; public class BusTest { public static void main(String[] args) { Bus bus = new Bus(20); bus.print(); } }
子类构造方法没有通过super显示调用父类的有参构造方法,也没有通过this显示调用自身的其他构造方法时,系统会默认调用父类的无参构造方法
子类构造方法通过super显示调用父类的有参构造方法时,执行父类相应的构造方法,而不执行父类无参构造方法
子类构造方法通过this显示调用自身的其他构造方法,在相应构造方法中应用以上的两条规则
四、深入理解方法重写
方法重写规则
方法名称相同
参数列表相同
返回值类型相同或者是其子类
访问权限不可以严于父类
父类的静态方法不可以背子类覆盖为非静态方法,父类的非静态方法不可以背子类覆盖为静态方法
子类可以定义于父类同名的静态方法,以便在子类中隐藏父类的静态方法(静态方法中无法使用super)
父类的私有方法不可以被子类覆盖
不可以跑出比父类方法更多的异常
package cn.zhz.Kind; public class Father { public void m1() { System.out.println("父类的m1的方法"); } //同一个类中同名不同参的是方法重载 public String m1(int num1){ return "test"; } //方法返回值类型可以是自定义的数据类型 public Father m2() { System.out.println("父类的m2方法"); return new Father(); } public static void m3(){ System.out.println("父类的静态方法m3"); } private void m4(){ System.out.println("父类的私有方法m4"); } }
package cn.zhz.Kind; public class Son extends Father { //子类重写方法不可以比父类方法访问权限小,可以扩大方法的访问权限 //子类方法只要访问权限不严于父类,就构成了方法重写 public void m1() { System.out.println("子类重写后的m1方法"); } //方法重写是父子类的同名同参的 //子类方法返回值类型可以是父类方法返回值类型的子类,也是方法重写 public Son m2() { System.out.println("子类重写后的m2方法"); return new Son(); } /* 父类的静态方法不能被重写为非静态方法 反之,父类的非静态方法也不可以被重写为静态方法 public void m3(){ System.out.println("子类的非静态方法m3"); } */ //在子类中可以定义和父类一模一样的静态方法 public static void m3(){ //在静态方法中不可以使用super // super.m3(); Father.m3(); System.out.println("子类的非静态方法m3"); } public static void main(String[] args) { Son son = new Son(); son.m1(); son.m2(); Son.m3(); } }
比较项 | 位置 | 方法名称 | 参数列表 | 返回值 | 权限访问修饰符 |
方法重写 | 子类 | 相同 | 相同 | 相同或是其子类 | 不可以比父类更严格 |
方法重载 | 同类 | 相同 | 不相同 | 无关 | 无关 |
到此这篇关于Java基础之方法重写详解的文章就介绍到这了,更多相关java方法重写内容请搜索我们以前的文章或继续浏览下面的相关文章希望大家以后多多支持我们!