在JAVA中,一个类同时继承且实现时,父类与实现接口存在相同方法名的抽象方法时,如何处理?实现多个接口时,存在相同抽象方法名,如何处理?

先说结论:

结论1、当父类和实现的接口之间,存在同名方法时,就近优先实现父类的抽象方法。

结论2、当同名方法同时触发重写时,方法的:返回值类型、参数列表完全相同,实现类权限修饰符大于任意父类、接口的权限修饰符时(即:仅权限修饰符满足重载要求时)。可视为方法完全相同。

所以:子类一次重写即可,视为同时满足方法的重写,不会报错。

结论3、当同名方法触发重写时,参数列表不同、并且权限修饰符满足重载要求时(仍可确定是谁的方法时)。

所以:子类可分别重写这些方法,不会报错。

结论4、当同名方法触发重写时,参数列表相同、返回值类型不同、并且权限修饰符满足重载要求时,仅满足了重写的部分条件,无法识别究竟是哪个方法(毕竟返回值类型不同)。

所以:子类不可重写这些方法,报错。

注意:当接口的方法为default时(即默认方法),也是默认public修饰的,所以也需要高权限的public修饰符修饰。因为编译器会认为你在重写父类的方法时,也在重写接口的方法。所以就近原则仅限于条件完全相同的两个方法(即:权限修饰符、返回值类型、方法名)。

所以当遇到这种情况时:

1、先看方法的重写条件是否完全相同,若完全相同可视为同一方法。大家公用。

2、若不相同,再看参数列表,如果参数列表不同,支持各自重写,不会报错。

3、如果参数列表相同,看返回值类型是否相同,如果不同,无论怎么写,都会报错。

4、如果接口的方法为default,要看默认方法的权限修饰符是什么,一般来说都是public。

目录

1、方法名、权限修饰符、返回类型。参数列表相同。

2、方法名相同、返回类型、参数列表相同,但是权限修饰符不相同,需要顾及重写的规则。

3、方法名相同,返回类型、权限修饰符相同,但是参数列表不相同。

4、方法名、参数列表、权限修饰符相同,返回类型不相同。

1、方法名、权限修饰符、返回类型。参数列表相同。

一次重写即可。不会报错。

IDEA会提示你A1需要实现的是父类的抽象方法。

可见,当父类和接口同时存在完全相同的方法时,就近优先实现父类的方法。

public class T1 {
    public static void main(String[] args) {
        new A1().test1();// 输出:我实现了父类的方法
    }
}
public class A1 extends B1 implements C1 {
    @Override
    public void test1() {
        System.out.println("我实现了父类的方法");
    }
}
public abstract class B1 {
    public abstract void test1();
}
public interface C1 {
    void test1();
}

2、方法名相同、返回类型、参数列表相同,但是权限修饰符不相同,需要顾及重写的规则。

若违反重写的概念,报错。如:

public class T1 {
    public static void main(String[] args) {
        new A1().test1();
    }
}
public class A1 extends B1 implements C1 {
    @Override
    protected void test1() {
        // 违反了重写的概念:修饰符只可大于或者等于父类、接口的权限修饰符
        System.out.println("我实现了父类的方法");
    }
}
public abstract class B1 {
    public abstract void test1();
}
public interface C1 {
    void test1();
}

接口的默认方法也是public修饰的

public class T1 {
    public static void main(String[] args) {
        new A1().test1();
    }
}
public class A1 extends B1 implements C1 {
    @Override
    protected void test1() {
        // 默认方法也是public修饰的,但是默认方法不会强制重写,
        // 但是方法名相同,编译器会认为你在重写,所以使用protected会报错
        System.out.println("我实现了父类的方法");
    }
}
public abstract class B1 {
    protected abstract void test1();
}
public interface C1 {
    default void test1(){};
}

3、方法名相同,返回类型、权限修饰符相同,但是参数列表不相同。

父类和这些接口的方法可以各自重写

public class T1 {
    public static void main(String[] args) {
        new A1().test1();
    }
}
public class A1 extends B1 implements C1 {

    @Override
    public void test1(String s) {
        System.out.println("我实现了父类的方法");

    }

    @Override
    public void test1() {
        System.out.println("我实现了接口的方法");
    }
}
public abstract class B1 {
    public abstract void test1(String s);
}
public interface C1 {
   void test1();
}

即便是返回值类型不同,也依然可以各自重写。

public class T1 {
    public static void main(String[] args) {
        new A1().test1();
    }
}
public class A1 extends B1 implements C1 {

    @Override
    public String test1(String s) {
        System.out.println("我实现了父类的方法");
        return null;

    }

    @Override
    public void test1() {
        System.out.println("我实现了接口的方法");
    }
}
public abstract class B1 {
    public abstract String test1(String s);
}
public interface C1 {
   void test1();
}

4、方法名、参数列表、权限修饰符相同,返回类型不相同。

正如以上所说,这种情况你可以视为是同一个方法的重载,但是同名方法,参数列表相同,唯独返回值类型不同,既不满足重载,也不满足重写的规范。

这种情况本身就是违背重载的定义的。所以报错

public class T1 {
    public static void main(String[] args) {
        new A1().test1();
    }
}
public class A1 extends B1 implements C1 {
    @Override
    public String test1() {
        // 无论你改成void 还是 String 都一样报错。
        return null;
    }
}
public abstract class B1 {
    public abstract String test1();
}
public interface C1 {
   void test1();
}

参数列表不同的情况,一样是可以分别重写的。

public class T1 {
    public static void main(String[] args) {
        new A1().test1();
    }
}
public class A1 extends B1 implements C1 {
    
    @Override
    public String test1(String s) {
        return null;
    }
    
    @Override
    public void test1() {

    }
}
public abstract class B1 {
    public abstract String test1(String s);
}
public interface C1 {
   void test1();
}

如有问题,望指正,看到这里感谢您的支持。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值