子类一定要重写接口中定义的方法吗?

本文探讨Java中当抽象类的非抽象方法与接口中的方法重合时,子类继承和实现的行为。子类如何选择调用哪个方法,以及重写后的多态性。理解'类优先'原则和接口的抽象特性。

Java摒弃了C++中的多重继承,只支持单继承,但是可以通过接口实现“多继承”的效果。如果一个非抽象子类继承了一个抽象类的同时又实现了某个接口,赶巧的是这个抽象类包含的非抽象方法与接口中的方法相同,那么当子类使用该方法时会发生什么?先来看看第一个例子:

定义一个抽象类AbstractTest,包含一个非抽象方法test返回值类型为void,参数类型为String,如下:

public abstract class AbstractTest {

    public void test(String testStr){
        System.out.println(testStr + ":Abstract 非抽象方法被调用");
    }

}

定义一个接口InterfaceTest,接口中定义test返回值类型为void,方法参数类型String,与上面的抽象类中的方法相同,如下:

public interface InterfaceTest {

    void test(String testStr);

}

定义一个子类TestClass,继承抽象类AbstractTest实现接口InterfaceTest,且不重写test方法先来看一下,如下:

public class TestClass extends AbstractTest implements InterfaceTest {

    public static void main(String[] args) {
        TestClass testClass = new TestClass();
        testClass.test("我调用了谁?");
    }
}

执行main方法,程序运行结果如下:
在这里插入图片描述

从程序运行结果来看,我们的TestClass 可以不声明接口中的方法而且可以调用test方法,具体执行为抽象类AbstractTest中的test方法,
结论: 在抽象类中的非抽象方法与接口中的方法相同时,继承该抽象类以及实现该接口的子类可以不声明接口中的方法,具体调用的为抽象中的方法。这正体现了Java中的“类优先”法则。

那么当子类重写test方法时,又会怎样?

下面将TestClass稍作改造,重写test方法,如下:

public class TestClass extends AbstractTest implements InterfaceTest {

    @Override
    public void test(String str){
        System.out.println(str +"子类重写的test方法被调用");
    }

    public static void main(String[] args) {
        TestClass testClass = new TestClass();
        testClass.test("我调用了谁?");
    }
}

再次执行main方法,程序运营结果如下:

在这里插入图片描述

结论: 当子类重写test方法后,不管是抽象类中非抽象方法还是接口中的方法,当子类重写时,具体调用为子类重写后的方法,这样其实保证了Java的向后兼容以及高扩展性,体现了Java中的多态理念。

在对我们的例子进行一下改造,在抽象类AbstractTest中添加抽象方法testMethod 以及在接口中添加相同方法,如下:

抽象类AbstractTest如下:

public abstract class AbstractTest {

    public void test(String testStr){
        System.out.println(testStr + ":Abstract 非抽象方法被调用");
    }

    public abstract void testMethod(String str);

}

接口InterfaceTest如下:

public interface InterfaceTest {

    void test(String testStr);

    void testMethod(String str);

}

由于抽象类中的抽象方法以及接口中的方法必须要重写,所以子类需要重写testMethod方法,如下:

public class TestClass extends AbstractTest implements InterfaceTest {

    @Override
    public void test(String str){
        System.out.println(str +"子类重写的test方法被调用");
    }

    @Override
    public void testMethod(String str) {
        System.out.println(str + "抽象类的抽象方法和接口方法必须重写");
    }

    public static void main(String[] args) {
        TestClass testClass = new TestClass();
        testClass.test("我调用了谁?");
        testClass.testMethod("Hello?");
    }
}

执行main方法,程序运行结果如下:

在这里插入图片描述

结论: 当抽象类中的抽象方法与接口中的方法相同时,子类必须重写该方法,体现Java中的抽象类接口的特点。

综合上面的例子可以看到接口是比抽象类更加抽象的一种形式,当抽象类中的非抽象方法与接口中的相同时,子类可以不显示实现该方法,但具体调用一定是重写了该方法,只不过在这种特殊的情况下,子类继承了抽象类中的方法用以实现。
ava中的抽象类接口的特点。

综合上面的例子可以看到接口是比抽象类更加抽象的一种形式,当抽象类中的非抽象方法与接口中的相同时,子类可以不显示实现该方法,但具体调用一定是重写了该方法,只不过在这种特殊的情况下,子类继承了抽象类中的方法用以实现。

### Java 接口子类是否必须重写所有方法Java 中,接口子类是否需要重写接口中的所有方法取决于具体情况。以下是对该问题的详细分析: #### 1. 接口的默认方法Java 8 开始,接口可以包含默认方法(`default` 方法)。这意味着接口的实现不需要强制实现这些默认方法[^3]。如果子类没有提供自己的实现,则会直接使用接口定义的默认方法。 例如: ```java public interface MyInterface { default void defaultMethod() { System.out.println("This is a default method."); } void abstractMethod(); } public class MyClass implements MyInterface { @Override public void abstractMethod() { System.out.println("Implementation of abstract method."); } } ``` 在这个例子中,`MyClass` 不需要实现 `defaultMethod`,因为它已经由接口 `MyInterface` 提供了默认实现。 #### 2. 抽象类实现接口 当一个抽象类实现接口时,它可以选择不实现接口中的某些方法。这些未实现的方法可以留给具体的子类去实现[^2]。因此,在这种情况下,子类并不需要重写接口中的所有方法。 示例代码如下: ```java interface N { void content(); void copy(); } abstract class M implements N { @Override public void content() { System.out.println("Parent class implementation of content method."); } } public class Main extends M { @Override public void copy() { System.out.println("Child class implementation of copy method."); } public static void main(String[] args) { Main main = new Main(); main.content(); // 调用父实现的方法 main.copy(); // 调用子类实现的方法 } } ``` #### 3. 普通实现接口 如果一个普通实现了某个接口,那么该必须实现接口中所有的抽象方法,除非该本身是抽象类[^1]。这是因为在 Java 中,普通不能留有任何未实现的抽象方法。 例如: ```java public interface MyInterface { void methodOne(); void methodTwo(); } public class MyClass implements MyInterface { @Override public void methodOne() { System.out.println("Implementation of methodOne."); } @Override public void methodTwo() { System.out.println("Implementation of methodTwo."); } } ``` #### 4. 总结 - 如果接口中的方法被标记为 `default`,则其实现无需强制重写这些方法。 - 如果一个抽象类实现了接口,它可以不实现接口中的某些方法,而将这些方法的实现留给具体的子类。 - 如果一个普通实现了接口,则必须实现接口中所有的抽象方法,除非该本身也是抽象类。 ---
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

喵喵@香菜

感谢观众老爷送的一发火箭!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值