個人主頁-愛因斯晨
優秀文章推薦
文章目錄
- 個人主頁-愛因斯晨
- 優秀文章推薦
- 引言
- 一、三種調用機制概述
- C語言的庫函數
- Python 的導包機制
- Java 的 API 接口調用
- 綜上:
- 二、它們的相同點:封裝與調用
- 三、不同之處
- **對比核心維度**
- **細節串講**
- 1. **C 語言:最原始的“過程式調用”**
- 2. **Python:模塊化 + 面向對象**
- 3. **Java:純面向對象 + 嚴格接口**
- 通俗理解:不同“買菜方式”
- 四、統一視角下的“調用模型”
- 五、總結升華
引言
作為一個小菜鳥,在惡補C語言庫函數
的時候,聯想到這與Java
中的API接口
和Python
中的導入模塊
是不是本質上就是調用封裝好的代碼,在本語言中的能效是不是一樣的。我感覺應該是大差不差,但是做學問不能大差不差。于是,我悄悄的去查了一下,我猜對了哈哈。本質上是一樣的,思想上是一樣的,但在底層原理和調用機制上有些差別,也就是有了語言特色。我能有這樣的想法,值得小小的驕傲一下。抽象思考的開始就是在進步~
針對這一問題正文開始:
一、三種調用機制概述
我們先來看看這三種語言在代碼中的基本使用方式:
C語言的庫函數
C 是一種過程式語言,沒有類和對象的概念。我們使用 #include
指令引入標準庫頭文件,然后調用其中的函數。例如:
#include <stdio.h>int main() {printf("Hello, world!\n");return 0;
}
printf()
就是標準庫 stdio.h
中封裝好的一個函數。使用者無需關心其內部實現,只需知道用法即可。
Python 的導包機制
Python 提倡模塊化開發,標準庫和第三方庫都以“模塊”的形式存在,使用時通過 import
語句引入。例如:
import math
print(math.sqrt(25))
你也可以選擇性導入模塊中的某個函數:
from math import sqrt
print(sqrt(25))
模塊中可以包含函數、類、變量等內容。Python 的導入機制十分靈活,符合其動態解釋型語言的特性。
像這樣的常用的還有:
import numpy as np #數值計算
import pandas as pd #數據分析處理
import matplotlib.pyplot as plt #數據可視化
不要問博主為什么熟悉這三個模塊,問就是數模的痛啊!!
Java 的 API 接口調用
Java 是面向對象語言,一切都以“類”的方式封裝。我們通過 import
語句引入需要使用的類,再通過對象或靜態方式調用其方
法。例如:
import java.util.ArrayList;public class Demo {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("Hello");System.out.println(list.get(0));}
}
Java 的類庫龐大、分類嚴謹,并且有詳細的文檔支持(Java API 文檔),是開發中不可或缺的一部分。博主至今沒找到和阿偉
老師同一版的API文檔,有的小伙伴兒請分享給博主啊,主頁介紹有微信,求求了。博主的主要學習語言是java,Py
和C
學的
不深吶
綜上:
C語言庫函數是通過 #include
引入頭文件 + 鏈接庫文件。
Python 中通過 import
語句導入模塊或包。
Java 中通過 import
引入類/接口,通過 API 使用類庫功能。
二、它們的相同點:封裝與調用
我們看了他們的調用方式,現在來盤點一下就是是怎樣一個相同的本質:
無論是哪種語言,這些機制都有一個共同目標:
封裝好的功能模塊可直接調用,提升開發效率。
總結起來,它們都具備以下特征:
- 都是封裝調用機制
- 隱藏內部實現,暴露接口/函數/類
- 目的是復用代碼、提高效率
- 可組合使用,形成更大程序
注:有朋友可能會誤解:**封裝不是在java中才有的嗎?**在java中,封裝確實作為面向對象編程三大塊之一(封裝、繼承、多態)。
但不是它特有的,它是所有現代編程語言中普遍存在的一種軟件設計思想,只是 Java 對封裝的表達最為“顯式”和“制度化”,所
以很多人第一次認真接觸封裝,往往是在 Java 中。
三、不同之處
對比核心維度
比較維度 | C 語言(庫函數) | Python(導包) | Java(API 接口) |
---|---|---|---|
使用方式 | #include <stdio.h> | import math | import java.util.List |
調用方式 | printf() | math.sqrt() | list.get(0) |
類型 | 函數庫(頭文件+鏈接庫) | 模塊、包、類 | 類庫、接口、類 |
底層機制 | 靜態/動態鏈接 | 動態解釋器導入(模塊緩存) | JVM 加載 .class 文件 |
面向對象 | 否(過程式) | 是(支持 OOP) | 是(純 OOP) |
封裝靈活性 | 低(靠程序員自覺) | 高(可靈活封裝) | 中(封裝嚴格) |
細節串講
1. C 語言:最原始的“過程式調用”
- 用
#include
把頭文件里寫好的聲明引入進來(告訴編譯器有這些函數)。 - 真正的實現在
.c
文件里,通過編譯器生成的目標文件或鏈接庫.lib
/.so
/.dll
被鏈接進程序。 static
可以讓函數只在文件內可見,相當于局部封裝。- C 只提供了最小的封裝手段,程序員需要靠命名和約定去遵守接口和封裝(沒有訪問控制符)。
優點:非常靈活,高效。
缺點:沒有強制封裝和可擴展的模塊系統,容易踩坑。
2. Python:模塊化 + 面向對象
- 用
import
把整個模塊或其中部分成員引入到當前命名空間。 - 模塊可以包含變量、函數、類等,是功能單元。
- 通過
_
和__all__
機制來控制哪些是“對外接口”,哪些是“內部實現”。 - Python 解釋器在運行時動態加載模塊,會緩存到
sys.modules
中,效率高、靈活性強。
優點:組織方式靈活,既可以面向過程(只用函數),也可以面向對象(類、方法)。
缺點:訪問控制靠約定(下劃線命名),不是強制性的。
3. Java:純面向對象 + 嚴格接口
- 一切功能都在類中封裝,通過對象和方法調用。
import
是告訴編譯器/IDE你要用哪個包里的類,JVM 在運行時加載.class
文件。- 有明確的訪問修飾符:
public
、private
、protected
,配合interface
和abstract
保證了模塊之間只能通過“黑盒”方式調用。 - 強調文檔化(JavaDoc),接口設計盡可能穩定,方便多人協作和大型項目維護。
優點:封裝嚴格,依賴清晰,便于大型工程合作。
缺點:靈活性相對較低,不允許你隨便“越界”訪問實現細節。
舉個例子:你要計算平方根
- C語言:使用
sqrt()
,要鏈接 math 庫 - Python:
import math
后直接用math.sqrt()
- Java:用
Math.sqrt()
,它是標準類庫中靜態方法的一部分
注:讀到這里你有沒有聯想到函數?函數與這三者的本質一樣嗎?
答案是:是的,本質一樣,都是封裝好的功能單元的調用。
- 自己寫的函數:是你自己封裝的功能邏輯
- 庫函數/API:是別人寫好的封裝邏輯,你通過調用接口使用
它們的區別只是:
維度 | 自己寫的函數 | 庫函數 / 模塊 / API |
---|---|---|
實現者 | 你自己 | 第三方/語言標準庫 |
可控性 | 高(可改) | 低(只調用) |
抽象層次 | 局部封裝 | 系統/模塊級封裝 |
可以說,從函數 → 模塊 → API,是功能封裝粒度越來越大的過程。
通俗理解:不同“買菜方式”
可以用一個比喻來形象地理解它們:
- C語言像超市自己搬貨:你去超市買東西,得知道哪個貨架在哪,手動挑選并結賬(頭文件 + 鏈接庫)。
- Python像點外賣:你說“我要牛奶”,平臺自動給你送來,不用關心它從哪來的(解釋器動態導入模塊)。
- Java像公司采購:你申請一份需求,走審批流程,用標準接口對接供應商(類與接口,編譯與JVM約束更嚴格)。
四、統一視角下的“調用模型”
JAVA、C、Python 是這樣。那么我們格局打開:抽象所有調用方式,可以看到一個共同模型:
[調用者] ——(通過接口)——> [被調用者的封裝邏輯]
這個模型不依賴語言,不依賴調用方式。只要滿足:
- 有清晰的調用入口(接口、函數、方法)
- 有明確的封裝邊界(實現不可見)
- 有調用和被調用的分離(你調用的是“黑盒”)
那它就是一種“統一的調用機制”。是不是豁然開朗捏~
五、總結升華
? 可能我的這篇博客在資深程序員看來,像極了在論證一個已知的常識。就像我寫了2k字在論證人活著要呼吸一樣。其實我的這個思考對于我自身來說是有很大意義的,也可以算個進步的開始,開始有想法了。學編程不只是會用語言,而是在理解語言的“靈魂”——這才是編程真正的魅力所在。最后用一句話作為結尾,送給我,也送給不斷攀登的年輕人:
? 青年人的血液應該是液態陽光!