【java】java中函数加与不加abstract 的区别

在 Java 中,函数是否加 abstract 会影响其行为和所在类的设计方式。具体来说,abstract 关键字的使用决定了方法的实现方式和类的继承关系。下面是详细的解释:

1. 不加 abstract 的方法

  • 普通方法: 如果一个方法没有 abstract 关键字,它就是一个普通方法 。普通方法要么是已经实现的方法(即方法体已给出实现),要么是没有 abstract 的普通方法。

  • 可以在类中提供实现: 当你定义一个普通方法时,你为该方法提供了具体的实现。其他类可以继承这个方法并直接使用,或者重写它(如果是实例方法)。

    java 复制代码
    class Animal {
        void sound() {
            System.out.println("Animal sound");
        }
    }
    
    class Dog extends Animal {
        @Override
        void sound() {
            System.out.println("Bark");
        }
    }

    在这个例子中,sound() 是一个普通的已实现方法,Dog 类可以继承并重写该方法。

  • 可以被调用: 不加 abstract 的方法是可以直接被调用的,无需在子类中实现。

2. abstract 的方法

  • 抽象方法: 如果一个方法加了 abstract,那么它就是一个抽象方法。抽象方法没有方法体,也就是说,它只是方法的声明,表示这个方法的具体实现应该由子类来提供。

  • 必须在抽象类中定义: 抽象方法必须位于抽象类中。抽象类本身不能直接被实例化,它需要被子类继承,子类必须实现抽象类中的所有抽象方法,除非子类也是抽象类。

  • 没有方法体: 抽象方法没有具体的实现,它只定义了方法的签名(方法名、参数列表等),其具体行为(方法体)留给子类去实现。

    java 复制代码
    abstract class Animal {
        abstract void sound();  // 抽象方法,没有方法体
    }
    
    class Dog extends Animal {
        @Override
        void sound() {
            System.out.println("Bark");
        }
    }

    在这个例子中,sound() 是一个抽象方法,Dog 类必须实现它。

  • 强制要求子类实现: 如果一个子类继承了一个抽象类,那么子类必须实现所有继承自抽象类的抽象方法,除非子类本身也是抽象类。

3. abstract 与不加 abstract 的区别

特性 不加 abstract abstract
方法体 有方法体,即有具体实现 没有方法体,只声明方法签名(没有实现)
所在类 可以在普通类中,普通类可以被实例化 必须在抽象类中,抽象类不能直接实例化
子类的责任 子类可以继承或重写,非强制 子类必须实现该方法,除非子类本身是抽象类
是否可以直接调用 可以直接调用方法 不能直接调用,必须由子类实现后调用

4. 实例代码对比

普通方法示例:
java 复制代码
class Animal {
    void sound() {  // 普通方法
        System.out.println("Animal sound");
    }
}

class Dog extends Animal {
    @Override
    void sound() {  // 重写方法
        System.out.println("Bark");
    }
}

public class Test {
    public static void main(String[] args) {
        Animal animal = new Dog();
        animal.sound();  // 输出 "Bark"
    }
}

在这个例子中,sound() 是一个普通方法,它已经有了具体的实现。子类 Dog 可以选择重写它。

抽象方法示例:
java 复制代码
abstract class Animal {
    abstract void sound();  // 抽象方法,没有实现
}

class Dog extends Animal {
    @Override
    void sound() {  // 必须重写抽象方法
        System.out.println("Bark");
    }
}

public class Test {
    public static void main(String[] args) {
        Animal animal = new Dog();
        animal.sound();  // 输出 "Bark"
    }
}

在这个例子中,sound() 是一个抽象方法,Dog 类必须实现它。如果 Dog 不实现 sound(),编译时会出错。

5. 为什么使用抽象方法?

  • 定义模板方法: 抽象方法用于定义子类必须实现的行为,但是不指定具体的实现。它提供了一个"模板",子类根据自己的需求来完成方法的具体实现。

  • 强制子类实现: 使用抽象方法可以强制子类去实现某些方法,确保所有子类都具备这些方法的实现。

  • 实现多态: 通过抽象类和抽象方法,可以实现多态的设计,让不同的子类有不同的实现,符合面向对象的设计原则。


总结

  • 普通方法: 提供了具体的实现,可以直接调用。
  • 抽象方法: 没有实现,只是声明,强制子类提供具体实现。它们只能在抽象类中定义,子类必须重写它们。

希望这个解释清楚了两者的区别!如果还有疑问,欢迎继续提问!

相关推荐
你撅嘴真丑2 小时前
STL练习
开发语言·c++·算法
❀͜͡傀儡师2 小时前
SpringBoot与Artemis整合,实现航空行李追踪消息中枢系统
java·spring boot·后端
青云交2 小时前
Java 大视界 -- Java 大数据在智能交通高速公路收费系统优化与通行效率提升实战
java
Ulyanov2 小时前
Impress.js深度技术解析:架构基础与结构化设计
开发语言·前端·javascript
bybitq2 小时前
cmake构建c++项目时,vscode/cursor无法识别头文件路径,导致报错,解决方案
开发语言·c++·vscode
哪里不会点哪里.2 小时前
IoC(控制反转)详解:Spring 的核心思想
java·spring·rpc
充气大锤2 小时前
前端实现流式输出配合katex.js
开发语言·前端·javascript·ai·vue
麦兜*2 小时前
SpringBoot Actuator监控端点详解,打造生产级应用健康检查
java·spring boot·后端
无限进步_2 小时前
二叉搜索树(BST)详解:从原理到实现
开发语言·数据结构·c++·ide·后端·github·visual studio