方法的覆写
当我们的子类发生继承关系之后发生了与父类相同结构的功能,例如说属性或者方法产生的一种现象。
方法的覆写
当继承关系发生后,如果子类定义了与父类相同的方法时,就表示发生了覆写的操作。
代码示例:
class Person{
public void tell(){
System.out.println("俺们是个人");
}
}
class Student extends Person{
//此时定义了一个和父类方法相同的方法
//此方法覆写了Person类中的tell方法
public void tell(){ //方法体不同
System.out.println("我是个学生");
}
}
public class Demo {
public static void main(String[] args) {
//实例化的是子类对象
Student stu = new Student();
stu.tell();
}
}
输出结果:
我是个学生
Student stu = new Student();我们new的是Student(子类),所以就调用Student(子类)的方法,哪个方法被覆写了就调用覆写后的,如果没有被覆写,就调用父类中原本的方法。这就是覆写的概念。
-
那么如果说现在希望通过子类来调用父类中已经被覆写过的方法呢?
这个时候可以使用super关键字。直接在子类之中调用父类方法。
代码示例:
class Person{ public void tell(){ System.out.println("俺们是个人"); } } class Student extends Person{ public void tell(){ super.tell(); //使用super关键字调用父类方法 System.out.println("我是个学生"); } } public class Demo { public static void main(String[] args) { Student stu = new Student(); stu.tell(); } }
输出结果:
俺们是个人 我是个学生
关于this 与super调用方法的区别
-
使用this调用方法时,首先会通过本类进行查找,如果本类没有指定的方法存在,才会调用父类中定义的方法;
-
使用super调用方法时,会直接查找父类中的方法,即:不会找本类中定义过的方法。
覆写的概念
当子类定义了与父类的方法名称相同、参数类型及个数相同、返回值相同的方法时,就称为发生了覆写。但是被覆写的方法不能拥有比父类更为严格的访问控制权限。
实际上对于访问控制权限我们已经学习过三种了:
- public> default(什么都不写)> private.
- 如果说父类的方法权限为default,那么子类覆写方法的时候权限只能够是public或default;
- 如果说父类的方法权限为public,那么子类覆写方法的时候权限只能够是public。
代码示例:
class Person{
public void tell(){
System.out.println("俺们是个人");
}
}
class Student extends Person{
void tell(){ //用default(什么都不写)定义方法
System.out.println("我是个学生");
}
}
public class Demo {
public static void main(String[] args) {
Student stu = new Student();
stu.tell();
}
}
输出结果(报错):
java: Student中的tell()无法覆盖Person中的tell()
正在尝试分配更低的访问权限; 以前为public
以前是public,现在是default,权限变低了,这样不好。父类的权限高,子类的权限低呢
代码示例:
class Person{
void tell(){
System.out.println("俺们是个人");
}
}
class Student extends Person{
public void tell(){
System.out.println("我是个学生");
}
}
public class Demo {
public static void main(String[] args) {
Student stu = new Student();
stu.tell();
}
}
输出结果(正确):
我是个学生
- 如果父类的方法使用的是private,那么子类是无法覆写的。
代码示例01:
class Person{
public void fun(){
this.tell();
}
public void tell(){
System.out.println("俺们是个人");
}
}
class Student extends Person{
//此时定义了一个和父类方法相同的方法
//此方法覆写了Person类中的tell方法
public void tell(){ //方法体不同
System.out.println("我是个学生");
}
}
public class Demo {
public static void main(String[] args) {
Student stu = new Student();
stu.fun();//调用fun()方法时,tell()方法被调用,而子类中也有tell()方法,所以方法发生了覆写。
}
}
输出结果:
我是个学生
代码示例02:
class Person{
public void fun(){
this.tell();
}
private void tell(){
System.out.println("俺们是个人");
}
}
class Student extends Person{
public void tell(){
System.out.println("我是个学生");
}
}
public class Demo {
public static void main(String[] args) {
Student stu = new Student();
stu.fun();
}
}
代码中权限符合正常覆写要求。
输出结果:
俺们是个人
-
首先private定义的内容只能够在本类之中访问。那么在进行方法覆写的时候,如果子类定义的方法在父类之中的访问权限为private,那么子类是不能够进行覆写的,而子类即使按照覆写的要求编写方法。那么对于程序而言,也只是认为子类定义了一个新的操作,即:private定义的方法无法被覆写。
结论:以后只要是编写方法,99%得情况下都是用public进行定义。
属性的覆盖
属性的覆盖无实际意义,因为在类中属性都要用private进行封装。