在JAVA中,一个类同时继承且实现时,父类与实现接口存在相同方法名的抽象方法时,如何处理?实现多个接口时,存在相同抽象方法名,如何处理? |
您所在的位置:网站首页 › 定义类需要使用class关键字修饰 › 在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、方法名、参数列表、权限修饰符相同,返回类型不相同。正如以上所说,这种情况你可以视为是同一个方法的重载,但是同名方法,参数列表相同。 这种qingku本身就是违背重载的定义的。所以报错 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(); }如有问题,望指正,看到这里感谢您的支持。 |
今日新闻 |
推荐新闻 |
CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3 |