编程范式
以下从核心思想、特点、典型场景/语言角度:
一、基础分类:命令式 vs 声明式(最顶层分类)
-
命令式编程(核心:“怎么做”)
- 思想:像给计算机“一步步下指令”,详细描述实现目标的步骤。
- 特点:关注过程,你得告诉计算机“先做A,再做B,最后做C”。
- 典型代表:面向过程编程(如 C 语言写算法步骤)、大部分传统语言(Python/Java 写循环逻辑也算命令式)。
- 例子:“计算 1+2+…+100”,命令式会写
sum=0; for(i=1;i<=100;i++){ sum+=i }
,一步步教计算机求和。
-
声明式编程(核心:“是什么”)
- 思想:描述目标的结果/性质,不关心具体怎么实现,让计算机自己找方法。
- 特点:关注结果,你说“我要一个这样的东西”,计算机自己解决“怎么做”。
- 典型代表:SQL(写
SELECT * FROM table WHERE id=1
,不用管数据库怎么查)、React(JSX 描述 UI 长啥样,框架自己渲染)、函数式编程里的高阶抽象。 - 例子:还是“计算 1+2+…+100”,声明式可能写
sum(range(1,101))
(Python 的sum
函数内部帮你循环求和,你只声明“求这个范围的和” )。
二、细分范式(基于命令式/声明式衍生)
-
面向对象编程(OOP)
- 归属:命令式编程的细分(因为写代码时还是会一步步调对象方法),但思想更关注“对象交互”。
- 核心:把程序拆成“对象”(有属性和方法),通过对象之间的消息传递/方法调用解决问题。
- 特点:强调封装、继承、多态,适合复杂业务逻辑(如 Java 写电商系统,订单、用户都是对象)。
- 对比命令式:命令式可能平铺直叙写步骤,OOP 则把步骤封装到对象里,让对象自己管理状态。
-
函数式编程(FP)
- 归属:既可以是命令式(如 Python 的函数调用),也能融入声明式(如 Haskell 纯函数式),核心是“函数为一等公民”。
- 核心:用纯函数(无副作用、输入定则输出定) 组合解决问题,避免 mutable 状态。
- 特点:强调 immutable 数据、函数可作为参数/返回值,适合复杂数据处理(如 Scala 处理大数据流)。
- 对比 OOP:OOP 用对象存状态+方法改状态,FP 尽量不用可变状态,用函数嵌套/组合算结果。
-
面向过程编程
- 归属:命令式编程的最直接体现,完全按“步骤化”写代码。
- 核心:把程序拆成过程(函数/步骤),按顺序执行,数据在过程间传递。
- 特点:简单直接,但复杂项目里代码容易变“面条式”(逻辑纠缠)。
- 典型:C 语言写算法(如排序算法,一步步写交换、比较逻辑 )。
-
面向协议编程(POP,也叫面向接口编程)
- 归属:常和 OOP 结合,更关注“协议/接口”而非具体实现。
- 核心:定义协议(接口) 规定“必须有哪些行为”,具体对象实现协议,程序依赖协议而非具体类。
- 特点:解耦性强,适合框架开发(如 Swift 的 Protocol,Java 的 Interface )。
- 对比 OOP:OOP 可能直接依赖子类,POP 依赖协议,替换实现更灵活(如把“支付接口”换成微信/支付宝,只要实现协议即可 )。
三、一句话总结
- 最顶层分 命令式(教计算机一步步做) 和 声明式(告诉计算机想要什么结果)。
- 面向对象、面向过程、面向协议,都是命令式的细分(只是组织代码的方式不同);函数式编程可跨命令式/声明式,但更偏向声明式的简洁。
- 实际开发中,很多语言/项目是多范式混合(如 Python 同时支持 OOP、函数式、命令式 ),不用死抠“必须属于某一种”,理解核心思想即可~
以下是 Objective-C、Swift、SwiftUI、Flutter、Vue、Java、Python 等编程语言或框架所涉及的编程范式:
Objective-C
- 面向对象编程:Objective-C 是一种面向对象的编程语言,它以类和对象为基础。通过定义类来封装数据和方法,使用继承来实现代码的复用,通过多态来实现不同对象对同一消息的不同响应。例如,在开发 iOS 应用时,创建视图控制器类继承自
UIViewController
,然后添加自己的属性和方法来实现特定的功能。 - 命令式编程:在 Objective-C 中,开发者也会采用命令式编程的方式,按照顺序编写一系列的语句来实现具体的功能。比如在处理网络请求时,会依次编写建立连接、发送请求、处理响应等步骤的代码。
Swift
- 面向对象编程(OOP):Swift 支持类、继承、封装和多态等面向对象的特性。开发者可以定义类,通过类的实例来处理数据和执行操作,例如创建一个
Person
类,包含属性(如姓名、年龄)和方法(如打招呼),子类可以继承父类的属性和方法并进行重写 。 - 函数式编程(FP):Swift 提供了许多函数式编程的特性,比如闭包(Closure)。闭包是自包含的代码块,可以在代码中被传递和使用,类似于函数式编程中的函数。同时,Swift 的集合类型(如
Array
、Dictionary
)提供了一系列高阶函数,像map
、filter
、reduce
等,方便对集合中的元素进行操作,体现了函数式编程中数据不可变以及函数作为一等公民的思想。 - 面向协议编程(POP):这是 Swift 的一个重要编程范式。协议定义了一组方法、属性等要求,类型(类、结构体、枚举)通过遵循协议来实现这些要求。比如可以定义一个
Drawable
协议,规定实现该协议的类型必须具备绘制自身的方法,然后Rectangle
和Circle
结构体可以遵循这个协议并实现绘制方法。这使得代码具有更好的扩展性和解耦性。
SwiftUI
- 声明式编程:SwiftUI 主要采用声明式编程范式。开发者通过描述界面的最终状态,而不是一步步地命令式地构建界面。例如,定义一个按钮,只需要声明它的标题、样式以及点击后的行为,SwiftUI 框架会自动处理界面的渲染和更新。当数据发生变化时,SwiftUI 会根据声明的规则自动更新界面,不需要开发者手动去更新每一个视图元素。
Flutter
- 声明式编程:Flutter 使用 Dart 语言,其核心是声明式 UI 构建。开发者通过 Widget 来描述用户界面,当状态发生变化时,Flutter 会根据新的状态重新构建 Widget 树,从而更新界面。例如,定义一个
Text
Widget 和一个Button
Widget,当点击按钮改变数据时,相关的 Widget 会自动更新显示。 - 函数式编程:Dart 语言也支持函数式编程的一些特性,比如使用闭包来处理事件、对集合进行操作等。在 Flutter 开发中,闭包常用于处理按钮点击事件等场景 。
Vue
- 声明式编程:Vue 是一个渐进式的前端框架,采用声明式渲染。开发者通过编写 Vue 模板(或单文件组件中的模板部分)来描述视图结构,通过 Vue 的响应式系统,当数据发生变化时,视图会自动更新。例如,在模板中绑定数据到 HTML 元素,当数据改变时,对应的元素内容会自动更新。
- 组件化编程:这虽然不是传统意义上的编程范式,但在 Vue 开发中非常重要。Vue 允许将界面拆分成一个个独立的组件,每个组件有自己的状态和方法,组件之间可以通过 props 和事件进行通信,这有助于提高代码的复用性和可维护性。
Java
- 面向对象编程:Java 是一门典型的面向对象编程语言,全面支持类、对象、继承、封装、多态等面向对象的概念。在企业级应用开发中,会创建大量的类来表示业务实体和逻辑,通过对象之间的交互来完成各种功能,比如在电商系统中,会有
Product
类、Order
类等。 - 命令式编程:Java 代码中也包含大量的命令式编程风格,比如使用
for
循环、while
循环来处理数据,按照顺序执行一系列的语句来完成任务。 - 函数式编程:自从 Java 8 引入了 lambda 表达式和流(Stream)API 后,Java 也具备了一些函数式编程的能力。通过流 API 可以对集合进行
map
、filter
、reduce
等操作,lambda 表达式可以方便地定义匿名函数。
Python
- 命令式编程:Python 可以很自然地编写命令式代码,通过顺序执行语句、使用条件判断和循环结构来实现功能。例如,使用
for
循环遍历列表,对每个元素进行操作。 - 面向对象编程:Python 支持面向对象编程,能够定义类和对象,实现继承、封装和多态。在开发大型项目时,通过类来组织代码,提高代码的可维护性和复用性。
- 函数式编程:Python 提供了一些函数式编程的特性,比如函数可以作为参数传递、返回值返回,支持 lambda 表达式(匿名函数),还提供了
map
、filter
、reduce
等函数,方便对数据进行处理。此外,Python 的装饰器也是函数式编程思想的一种体现。 - 脚本式编程:Python 也常被用于脚本编写,快速实现一些自动化任务,它简洁的语法和动态类型系统使得脚本编写非常便捷。
这些编程语言和框架在实际应用中,往往会融合多种编程范式,以适应不同的开发场景和需求。
Text
class YZHomePage extends StatelessWidget {
const YZHomePage({super.key});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("基础组件"),
),
body: Text(
"黄色的树林里分出两条路,可惜我不能同时去涉足,我在那路口久久伫立,我向着一条路极目望去,直到它消失在丛林深处",
textAlign: TextAlign.center,
maxLines: 1,///最大行数
overflow: TextOverflow.ellipsis,///如果被省略了,省略号结束
textScaleFactor: 0.5,///缩放因子
style: TextStyle(
fontSize: 25,
color: Colors.pink,
fontWeight: FontWeight.bold
),
),
);
}
}
富文本
import 'package:flutter/material.dart';
main() => runApp(MyApp());
class MyApp extends StatelessWidget {
const MyApp({super.key});
Widget build(BuildContext context) {
return const MaterialApp(
home: YZHomePage(),
);
}
}
class YZHomeButtonPage extends StatelessWidget {
const YZHomeButtonPage({super.key});
Widget build(BuildContext context) {
return const Placeholder();
}
}
class YZHomePage extends StatelessWidget {
const YZHomePage({super.key});
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text("基础组件"),
),
body: YZHomeTextContent()
);
}
}
class YZHomeTextContent extends StatefulWidget {
const YZHomeTextContent({super.key});
State<YZHomeTextContent> createState() => _YZHomeTextContentState();
}
class _YZHomeTextContentState extends State<YZHomeTextContent> {
Widget build(BuildContext context) {
return Column(
children: [
Text(
"黄色的树林里分出两条路,可惜我不能同时去涉足,我在那路口久久伫立,我向着一条路极目望去,直到它消失在丛林深处",
textAlign: TextAlign.center,
maxLines: 3,///最大行数
overflow: TextOverflow.ellipsis,///如果被省略了,省略号结束
textScaleFactor: 1.2,///缩放因子
style: TextStyle(
fontSize: 25,
color: Colors.yellow,
fontWeight: FontWeight.bold
),
),
/// 符文本
Text.rich(
TextSpan(
text: "Hello OC",
style: TextStyle(color: Colors.green, fontSize: 28),
)
),
Text.rich(
TextSpan(
/// 符文本有多个
children: [
TextSpan(
text: "Hello Swift",
style: TextStyle(color: Colors.yellow, fontSize: 15),
),
TextSpan(
text: "Hello SwiftUI",
style: TextStyle(color: Colors.pink, fontSize: 15),
),
WidgetSpan(child: Icon(Icons.face, color: Colors.lightBlueAccent,)),
TextSpan(
text: "Hello Flutter",
style: TextStyle(color: Colors.purple, fontSize: 15),
),
],
)
),
],
);
}
}
按钮
class _YZHomeButtonContentState extends State<YZHomeButtonContent> {
Widget build(BuildContext context) {
return Column(
children: [
ElevatedButton(
onPressed: (){
print("ElevatedButton");
},
style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.green)),
child: Text("ElevatedButton", style: TextStyle(color: Colors.red)),
),
TextButton(
onPressed: (){
print("TextButton");
},
child: Text("TextButton")
),
OutlinedButton(
onPressed: (){
print("OutlinedButton");
},
child: Text("OutlinedButton")
),
///自定义按钮
TextButton(
onPressed: (){
print("TextButton");
},
child: Row(
/// 默认是占宽度全屏,加上下面这句,就占本身大小
mainAxisSize: MainAxisSize.min,
children: [
Icon(Icons.favorite),
Text("I Love You!")
],
),
style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.cyan)),
),
],
);
}
}
图片
class _YZHomeImageContentState extends State<YZHomeImageContent> {
Widget build(BuildContext context) {
return Column(
children: [
// 网络图片
Image(image: NetworkImage("https://profile-avatar.csdnimg.cn/6048fbe7bbe8476182ccb4e1364f988f_iosshan.jpg!1")),
// 本地图片 - 添加错误处理
Image.asset(
color: Colors.red,
colorBlendMode: BlendMode.colorBurn,
"assets/images/1211.png",
width: 200,
errorBuilder: (context, error, stackTrace) {
return Container(
width: 200,
height: 100,
color: Colors.grey[300],
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.error, color: Colors.red),
Text("图片加载失败", style: TextStyle(color: Colors.red)),
Text("请检查 assets/images/1211.png 是否存在", style: TextStyle(fontSize: 12)),
],
),
);
},
),
// 使用 AssetImage 的方式
Image(
color: Colors.yellow,
colorBlendMode: BlendMode.difference,
image: AssetImage("assets/images/1211.png"),
width: 200,
errorBuilder: (context, error, stackTrace) {
return Container(
width: 200,
height: 100,
color: Colors.grey[300],
child: Column(
mainAxisAlignment: MainAxisAlignment.center,
children: [
Icon(Icons.error, color: Colors.red),
Text("AssetImage 加载失败", style: TextStyle(color: Colors.red)),
Text("错误: $error", style: TextStyle(fontSize: 10)),
],
),
);
},
),
],
);
}
}
按钮紧挨着、placehold图片、Icon、输入框
class _YZHomeTextContentState extends State<YZHomeTextContent> {
final usernameController = TextEditingController();
final passwordController = TextEditingController();
Widget build(BuildContext context) {
return Column(
// 1. 消除 Column 子组件之间的默认垂直间距
//mainAxisSize: MainAxisSize.min, // 让 Column 仅占用子组件所需空间
children: [
TextButton(
onPressed: (){
},
child:Text("TextButton1"),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.lightBlueAccent),
// 去除按钮的外边距(默认可能存在微小外边距,这里确保彻底清除)
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
),
TextButton(
onPressed: (){
},
child:Text("TextButton2"),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.lightGreen),
// 去除按钮的外边距(默认可能存在微小外边距,这里确保彻底清除)
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
),
),
/// 没有文字的按钮,不显示
TextButton(
onPressed: (){
},
child:Text(""),
style: ButtonStyle(
backgroundColor: MaterialStateProperty.all(Colors.lightGreen),
// 去除按钮的外边距(默认可能存在微小外边距,这里确保彻底清除)
tapTargetSize: MaterialTapTargetSize.shrinkWrap,
/// 下面两个属性设置,将没有文字的按钮大小,设置为0
// 移除最小宽度和高度
minimumSize: MaterialStateProperty.all(Size.zero),
// 移除内边距
padding: MaterialStateProperty.all(EdgeInsets.zero),
),
),
/// 占位图
FadeInImage(
placeholder:AssetImage("assets/images/1211.png"),
image: NetworkImage("https://profile-avatar.csdnimg.cn/6048fbe7bbe8476182ccb4e1364f988f_iosshan.jpg!1"),
),
/// Icon
Icon(
Icons.pets,
color: Colors.lightGreen,
size: 120,
shadows: [
Shadow(
color: Colors.black26,
offset: Offset(5, 5)
)
],
),
Padding(
padding: EdgeInsets.all(10),
///TextField
child: TextField(
decoration: InputDecoration(
icon: Icon(Icons.face),
iconColor: Colors.greenAccent,
labelText: "请输入内容:",
border: OutlineInputBorder(borderSide: BorderSide(color: Colors.grey, width: 1))
),
onChanged: (value) {
print("输入内容: $value");
},
onSubmitted: (value) {
print("提交内容: $value");
},
controller: usernameController,
),
),
Padding(
padding: EdgeInsets.all(10),
///TextField
child: TextField(
decoration: InputDecoration(
icon: Icon(Icons.lock),
iconColor: Colors.greenAccent.withOpacity(0.8),
labelText: "请输入密码:",
border: OutlineInputBorder(borderSide: BorderSide(color: Colors.grey, width: 1))
),
controller: passwordController,
),
),
Container(
width: 320,
height: 44,
child: TextButton(
onPressed: (){
final username = usernameController.text;
final password = passwordController.text;
print("账户:$username, 密码:$password");
},
child: Text("登 录", style: TextStyle(color: Colors.white),),
style: ButtonStyle(backgroundColor: MaterialStateProperty.all(Colors.purple)),
)
)
],
);
}
}
Icon 
class _YZHomeTextContentState extends State<YZHomeTextContent> {
Widget build(BuildContext context) {
return Container(
width: 300,
height: 200,
child: Align(
alignment: Alignment(0.7, 0.6),//中心点是(0,0)
child: Transform.rotate(
angle: math.pi/(3),
child: Icon(
Icons.pets,
size: 50,
color: Colors.red,
),
)
),
decoration: BoxDecoration(
color: Colors.yellow,
borderRadius: BorderRadius.all(
Radius.elliptical(10, 10)
),
),
);
}
}
滚动Widget
布局
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
问:flutter里面的 Flexible以及Expanded的用法
在 Flutter 中,Flexible
和 Expanded
都是用于在 Row
、Column
或 Flex
等弹性布局中控制子组件尺寸的重要组件,它们能帮助子组件根据可用空间动态调整大小。
核心概念:弹性布局(Flex)
Row
、Column
本质上是 Flex
组件的特殊形式(Row
是水平方向的 Flex
,Column
是垂直方向的 Flex
)。弹性布局的核心是通过 flex
属性分配可用空间:
- 当父组件有剩余空间时,
flex
值越大的子组件,分到的空间越多; - 当空间不足时,会优先压缩
flex
值较小的组件(或未设置flex
的组件)。
1. Flexible
Flexible
允许子组件在可用空间内灵活调整尺寸,但不会强制子组件填满剩余空间,即子组件可以“按需收缩或扩展”,但不超过自身最大/最小限制。
常用属性:
flex
:整数,默认值为 1,用于分配剩余空间的比例(类似权重);fit
:控制子组件如何适应可用空间,有两个值:FlexFit.loose
(默认):子组件尺寸不超过自身最大限制(按需扩展,不强制填满);FlexFit.tight
:子组件必须填满分配到的空间(强制扩展)。
示例:
Row(
children: [
Container(width: 50, height: 50, color: Colors.red),
// 剩余空间按 1:2 分配给两个 Flexible
Flexible(
flex: 1,
fit: FlexFit.loose, // 默认,不强制填满
child: Container(height: 50, color: Colors.green),
),
Flexible(
flex: 2,
fit: FlexFit.tight, // 强制填满分配的空间
child: Container(height: 50, color: Colors.blue),
),
],
)
- 红色容器固定宽度 50;
- 剩余空间中,绿色占 1 份(
loose
模式,宽度不超过自身内容或限制),蓝色占 2 份(tight
模式,强制填满分配的空间)。
2. Expanded
Expanded
是 Flexible
的子类,它等价于 Flexible(fit: FlexFit.tight)
,即强制子组件填满分配到的所有可用空间。
常用属性:
- 仅
flex
属性(默认值 1),功能与Flexible
的flex
一致。
示例:
Row(
children: [
Container(width: 50, height: 50, color: Colors.red),
// 等价于 Flexible(flex:1, fit: FlexFit.tight)
Expanded(
flex: 1,
child: Container(height: 50, color: Colors.green),
),
Expanded(
flex: 2,
child: Container(height: 50, color: Colors.blue),
),
],
)
- 红色容器固定宽度 50;
- 剩余空间按 1:2 分配给绿色和蓝色容器,且两者都会强制填满分配到的空间(宽度随父组件变化)。
关键区别
特性 | Flexible | Expanded |
---|---|---|
本质 | 基础弹性组件 | Flexible 的子类(fit: tight ) |
空间填充 | 可选(loose 不强制,tight 强制) | 强制填满分配的空间 |
适用场景 | 子组件尺寸需保留上限(如文本换行) | 子组件需占满剩余空间(如列表项) |
典型使用场景
-
Expanded 适用场景:
- 列表项中需要占满剩余宽度的文本或按钮;
- 平分空间的布局(如三个按钮平均占满一行)。
// 三个按钮平分一行 Row( children: [ Expanded(child: ElevatedButton(onPressed: () {}, child: Text("按钮1"))), Expanded(child: ElevatedButton(onPressed: () {}, child: Text("按钮2"))), Expanded(child: ElevatedButton(onPressed: () {}, child: Text("按钮3"))), ], )
-
Flexible 适用场景:
- 文本内容可能过长,需要自动换行(
loose
模式避免文本被强制拉伸); - 子组件有最大尺寸限制,不希望超过该限制。
// 文本过长时自动换行,不强制占满空间 Row( children: [ Container(width: 80, height: 40, color: Colors.grey), Flexible( child: Text( "这是一段可能很长的文本,Flexible会让它在剩余空间内换行,而不是被强制拉伸", softWrap: true, ), ), ], )
- 文本内容可能过长,需要自动换行(
总结
- Expanded 是
Flexible(fit: FlexFit.tight)
的简写,强制子组件填满分配的空间,适合需要占满剩余空间的场景; - Flexible 更灵活,通过
fit
控制子组件是否强制填满空间,适合子组件有尺寸限制或需要保留自然大小的场景; - 两者都通过
flex
属性分配空间比例,flex
值越大,分到的空间越多。
Stack
class _YZHomeStackContentState extends State<YZHomeStackContent> {
Widget build(BuildContext context) {
return Stack(
alignment: Alignment.bottomRight,//默认左上角
// fit: StackFit.expand,//将所以子元素拉伸最大化
children: [
Image(image: AssetImage("assets/images/1211.png"), height: 500,),
Container(
height: 200,
width: 200,
color: Colors.greenAccent,
),
Positioned(
right: 10,
bottom: 10,
child:Text("这是一个标题描述")
)
],
);
}
}