面向对象编程:Swift中的类和结构体

发布时间: 2024-01-26 17:44:16 阅读量: 30 订阅数: 29
# 1. 理解面向对象编程 ## 1.1 什么是面向对象编程 面向对象编程(Object-Oriented Programming,简称OOP)是一种编程范式,它将程序分解为多个对象,每个对象都有自己的状态和行为。面向对象编程的核心思想是通过将数据和操作数据的方法组合在一起,使得程序更加模块化、可靠、易于理解和维护。 在面向对象编程中,对象是类的实例化。类是一种描述对象所具有的属性和行为的抽象模板。属性是对象的状态,行为是对象能够执行的操作。 ## 1.2 面向对象编程的特点 面向对象编程具有以下几个重要特点: - 封装(Encapsulation):将数据和操作数据的方法组合到一起,形成一个独立的实体,对外只暴露必要的接口,隐藏内部实现细节。 - 继承(Inheritance):通过继承机制,可以构建类与类之间的层次结构,子类可以继承并重用父类的属性和方法,减少代码重复。 - 多态(Polymorphism):不同的对象对同一消息可以有不同的响应方式,提供了灵活和动态的代码编写方式。 ## 1.3 面向对象编程与其他编程范式的对比 与面向对象编程不同,还有其他一些编程范式,例如: - 过程式编程:以过程(函数)为主要组织方式,通过对数据进行处理来实现程序的功能。 - 函数式编程:以函数为基本单位,将程序视为一系列函数的组合,强调不可变数据和无副作用。 - 声明式编程:通过描述问题的性质和约束来解决问题,而非一步一步指导计算机如何完成。 面向对象编程通过将数据和操作数据的方法封装在一起,更加符合人类思维方式,使得程序更具可读性、可维护性和可扩展性。因此,在编写Swift代码时,理解面向对象编程的概念和特点是非常重要的。 # 2. 类和结构体的基础 在面向对象编程中,类和结构体是两种最基本的概念。它们都可以被用来定义自己的属性和方法,从而用来创建对象和操作数据。在Swift中,类和结构体的定义非常相似,但也有一些区别。接下来,我们将详细介绍类和结构体的基本知识。 #### 2.1 类和结构体的定义 在Swift中,可以使用关键字`class`来定义一个类,用关键字`struct`来定义一个结构体。它们的定义方式如下: ```swift // 定义一个类 class MyClass { // 类的属性和方法 } // 定义一个结构体 struct MyStruct { // 结构体的属性和方法 } ``` 类和结构体都可以拥有自己的属性和方法,用来描述对象的特征和行为。例如,我们可以定义一个表示人的类和结构体: ```swift // 类的定义 class Person { var name: String var age: Int init(name: String, age: Int) { self.name = name self.age = age } func sayHello() { print("Hello, my name is \(name).") } } // 结构体的定义 struct PersonStruct { var name: String var age: Int func sayHello() { print("Hello, my name is \(name).") } } ``` #### 2.2 属性和方法 类和结构体中的属性和方法用于描述对象的特征和行为。属性可以是实例属性或类型属性,方法可以是实例方法或类型方法。 实例属性和方法是属于类或结构体的每个实例的特征和行为。通过创建类或结构体的实例,我们可以访问和修改它们。例如,我们可以创建一个`Person`类的实例,并访问它的属性和调用它的方法: ```swift let person = Person(name: "John", age: 25) print(person.name) // 输出: John person.sayHello() // 输出: Hello, my name is John. ``` 类型属性和方法是属于类或结构体本身的特征和行为,而不是属于实例。它们可以在类或结构体的定义中使用关键字`static`或`class`来声明。不同之处在于,用`class`关键字声明的类型属性或方法可以被子类重写,而用`static`关键字声明的不能被子类重写。例如,我们可以定义一个表示数学计算的`Math`类,其中包含一个类型方法用于计算两个数的和: ```swift class Math { static func sum(a: Int, b: Int) -> Int { return a + b } } print(Math.sum(a: 3, b: 5)) // 输出: 8 ``` #### 2.3 初始化方法 类和结构体可以定义初始化方法,用于创建对象时进行一些必要的设置。在Swift中,可以使用关键字`init`来定义初始化方法。初始化方法的参数可以用于传递对象的初始状态。例如,我们可以为`Person`类添加一个初始化方法: ```swift class Person { var name: String var age: Int init(name: String, age: Int) { self.name = name self.age = age } // 其他属性和方法... } let person = Person(name: "John", age: 25) ``` 在上面的例子中,我们通过初始化方法设置了`Person`对象的`name`和`age`属性的初始值。通过传入参数,我们可以根据需要创建不同的对象。 ### 代码总结 本章介绍了类和结构体的基础知识。类和结构体都可以用来定义属性和方法,用于描述对象的特征和行为。类和结构体的定义方式相似,但也有一些区别。我们还介绍了属性和方法的分类(实例属性和方法、类型属性和方法),以及初始化方法的使用。在下一章中,我们将探讨类和结构体的比较,以及何时应该使用类或结构体的问题。 # 3. 类和结构体的比较 #### 3.1 类和结构体的区别 在Swift中,类和结构体是两种常见的数据类型,它们都可以用于创建自定义的复杂数据结构。虽然类和结构体在语法上非常相似,但它们之间存在一些关键的区别。 首先,类是引用类型,而结构体是值类型。这意味着当我们将一个类赋值给另一个变量或将其传递给函数时,实际上是将对同一个对象的引用传递给了新的变量或函数。而结构体在进行这些操作时,会进行值的拷贝。 ```swift class PersonClass { var name: String init(name: String) { self.name = name } } struct PersonStruct { var name: String } var personClass1 = PersonClass(name: "John") var personClass2 = personClass1 personClass2.name = "Jane" print(personClass1.name) // Output: Jane var personStruct1 = PersonStruct(name: "John") var personStruct2 = personStruct1 personStruct2.name = "Jane" print(personStruct1.name) // Output: John ``` 在上面的例子中,当我们将`personClass1`赋值给`personClass2`并修改`personClass2`的`name`属性时,`personClass1`的`name`属性也被修改了。而当我们将`personStruct1`赋值给`personStruct2`并修改`personStruct2`的`name`属性时,并不会影响到`personStruct1`的`name`属性。 此外,类还支持继承,这意味着可以通过创建一个子类来扩展现有的类,并重写父类的属性和方法。结构体不支持继承。这使得类在创建复杂的对象层次结构时非常有用。 #### 3.2 何时应该使用类或结构体 选择使用类还是结构体取决于你要解决的问题。一般来说,如果你需要创建一个拥有复杂层次结构且需要通过引用共享和修改的对象,或者需要使用继承来扩展已有功能,那么应该使用类。而如果你只需要创建一个轻量级的数据类型,需要拷贝而不是共享对象的话,应该使用结构体。 另外,结构体还有一个重要的特点是线程安全的。由于它是值类型,在多线程环境中使用时不需考虑多线程同步问题。所以,当数据不需要被多个线程同时修改时,结构体是一个更好的选择。 #### 3.3 引用类型和值类型 理解类和结构体的区别有助于我们更好地理解引用类型和值类型的概念。类是引用类型,它们的实例在被赋值给一个变量或传递给函数时,实际上是传递了对同一个对象的引用。而结构体是值类型,它们的实例在被赋值给一个变量或传递给函数时,实际上是进行了值的拷贝。 这种差别导致了在对类和结构体进行操作时的不同行为。操作类的实例时,修改一个变量会影响到所有引用到该对象的变量;而操作结构体的实例时,每个变量都会有自己独立的拷贝,互不影响。 在开发iOS应用时,我们需要根据具体的需求来选择使用类或结构体,并理解它们之间的差异,以便更好地管理和操作数据。 # 4. 类的继承与多态 在面向对象编程中,类的继承和多态是两个重要的概念。通过类的继承,我们可以创建一个新的类,它会从一个称为父类或基类的现有类继承属性和方法。通过多态,我们可以在不同的对象上调用相同的方法,但每个对象可能会以不同的方式实现该方法。 #### 4.1 类的继承 在Swift中,类的继承通过使用`class`关键字和冒号`:`来定义。下面是一个简单的示例: ```swift class Vehicle { var name: String init(name: String) { self.name = name } func move() { print("The vehicle is moving.") } } class Car: Vehicle { var brand: String init(name: String, brand: String) { self.brand = brand super.init(name: name) } override func move() { print("The car \(brand) is moving.") } } let myCar = Car(name: "MyCar", brand: "Tesla") myCar.move() // 输出:"The car Tesla is moving." ``` 在上面的示例中,`Vehicle`类定义了一个名为`name`的属性和一个名为`move`的方法。`Car`类继承自`Vehicle`类,并添加了一个名为`brand`的属性。它还对`move`方法进行了覆盖,以输出特定于汽车的消息。 #### 4.2 覆盖方法 通过在子类中定义与父类中同名的方法,我们可以实现对该方法的覆盖。在Swift中,我们使用`override`关键字来明确表示对父类方法的覆盖。下面是一个示例: ```swift class Animal { func makeSound() { print("The animal makes a sound.") } } class Dog: Animal { override func makeSound() { print("The dog barks.") } } let myDog = Dog() myDog.makeSound() // 输出:"The dog barks." ``` 在上面的示例中,`Animal`类定义了一个`makeSound`方法,而`Dog`类通过覆盖`makeSound`方法来实现了不同的行为。 #### 4.3 多态的实现 多态允许我们在父类引用变量中存储子类对象,并根据当前对象调用相应的方法。这是面向对象编程中的一个强大特性,可以提高代码的灵活性和可维护性。下面是一个示例: ```swift class Shape { func draw() { print("Drawing a shape.") } } class Circle: Shape { override func draw() { print("Drawing a circle.") } } class Rectangle: Shape { override func draw() { print("Drawing a rectangle.") } } let shapes: [Shape] = [Circle(), Rectangle()] for shape in shapes { shape.draw() } ``` 在上面的示例中,我们定义了一个`Shape`类和两个子类`Circle`和`Rectangle`。我们创建了一个`shapes`数组,其中存储了不同的形状对象。通过循环遍历该数组,并调用`draw`方法,我们可以看到不同的形状对象会分别调用自己的绘制方法。 输出结果: ``` Drawing a circle. Drawing a rectangle. ``` 这个示例展示了多态的特性,通过父类的引用变量来调用子类对象中重写的方法,实现了不同对象的不同行为。 在本章中,我们学习了类的继承和多态的概念,并看到它们在Swift中的应用。理解和熟练运用这些概念将帮助我们更好地设计和构建复杂的面向对象程序。 # 5. 结构体的应用 结构体是一种轻量级的数据结构,它在Swift中有着广泛的应用。与类相比,结构体更适合用于定义简单的数据类型,它们通常被用来封装相关的值,并可通过复制进行传递。 #### 5.1 结构体在Swift中的应用场景 结构体在Swift中可以应用于多个场景,包括但不限于: - 值类型的封装:当需要将多个相关的值封装成一个整体时,可以使用结构体。例如,在游戏中,一个玩家的属性(如姓名、生命值、等级)可以被封装为一个结构体来方便管理和传递。 ```swift struct Player { var name: String var health: Int var level: Int } var player1 = Player(name: "John", health: 100, level: 1) var player2 = player1 player2.name = "Alice" print(player1.name) // 输出: "John" print(player2.name) // 输出: "Alice" ``` - 值类型的传递:当需要将值类型传递给函数或方法时,可以使用结构体。相比于类,结构体通过复制传递值,而不是传递引用。这在一些特定场景下非常有用,例如在多线程环境下,避免数据共享和竞争条件。 ```swift struct Point { var x: Int var y: Int } func movePoint(_ point: Point) { var newPoint = point newPoint.x += 1 newPoint.y += 1 print("移动后的坐标:(\(newPoint.x), \(newPoint.y))") } var startPoint = Point(x: 0, y: 0) movePoint(startPoint) print("原始坐标:(\(startPoint.x), \(startPoint.y))") // 输出: "原始坐标:(0, 0)" ``` #### 5.2 结构体的优势与局限 结构体相比于类具有以下优势: - 高效性:因为结构体是值类型,它们通常会被直接分配在栈上,而不需要动态分配内存,这使得它们具有更高的性能。 - 多线程安全:由于结构体是值类型,它们在多线程环境中更容易维护数据的一致性和安全性,因为每个线程都拥有自己的副本,避免了数据竞争和共享问题。 结构体的局限性包括: - 不支持继承:与类不同,结构体不支持继承其他结构体或类,因此无法重用其他结构体或类的属性和方法。 - 功能较为有限:相比于类,结构体的功能较为有限,不能实现一些复杂的对象行为,例如析构方法和类型转换。 然而,结构体的优势使其在很多场景下成为首选,特别是对于简单的数据封装和值类型传递等需求。对于那些需要更复杂行为和继承特性的情况,类仍然是更合适的选择。 通过合理的选择和应用,结构体和类可以在Swift中提供强大的编程能力和灵活性,以满足不同的编程需求。 # 6. 最佳实践和设计模式 在本章中,我们将讨论面向对象编程的最佳实践和常用设计模式在Swift中的应用。这些实践和模式能帮助我们更好地组织和设计我们的代码,提高代码的可读性、可维护性和可扩展性。 ### 6.1 面向对象编程的最佳实践 在进行面向对象编程时,我们应该遵循一些最佳实践,以确保代码的质量和可维护性。 #### 6.1.1 单一职责原则(Single Responsibility Principle) 单一职责原则指一个类或模块应该有且只有一个改变的原因。这意味着每个类或模块应该只负责一项功能或任务。这样可以使代码更加清晰、可读和易于测试。 #### 6.1.2 开放封闭原则(Open-Closed Principle) 开放封闭原则指一个类或模块应该对扩展开放,对修改关闭。这意味着我们在进行功能增加或改变时,应该通过扩展现有的类或模块来实现,而不是修改原有的代码。这样可以减少对原有代码的影响,并保持代码的稳定性和可维护性。 #### 6.1.3 依赖倒置原则(Dependency Inversion Principle) 依赖倒置原则指高层模块不应该依赖于低层模块的具体实现,而应该依赖于抽象接口。这可以减少代码之间的耦合,使代码更加灵活和可扩展。 ### 6.2 常用设计模式在Swift中的应用 设计模式是一些被广泛应用于软件设计中的可复用解决方案。在Swift中,我们也可以使用一些常见的设计模式来解决一些常见的问题。 #### 6.2.1 单例模式(Singleton Pattern) 单例模式通过限制一个类只能有一个实例,来保证全局只有一个访问点。在Swift中,我们可以使用静态常量或静态属性来实现单例模式。 ```swift class Singleton { static let shared = Singleton() private init() {} func sayHello() { print("Hello, I'm a singleton!") } } let singleton = Singleton.shared singleton.sayHello() ``` #### 6.2.2 工厂模式(Factory Pattern) 工厂模式通过将对象的创建和使用分离,来实现对象的解耦和灵活性。在Swift中,我们可以使用工厂方法或抽象工厂来创建对象。 ```swift protocol Animal { func makeSound() } class Dog: Animal { func makeSound() { print("Woof!") } } class Cat: Animal { func makeSound() { print("Meow!") } } class AnimalFactory { static func createAnimal(type: String) -> Animal? { if type == "dog" { return Dog() } else if type == "cat" { return Cat() } return nil } } let dog = AnimalFactory.createAnimal(type: "dog") dog?.makeSound() let cat = AnimalFactory.createAnimal(type: "cat") cat?.makeSound() ``` #### 6.2.3 观察者模式(Observer Pattern) 观察者模式通过定义一对多的依赖关系,当一个对象的状态发生改变时,所有依赖它的对象都会得到通知并自动更新。在Swift中,我们可以使用NotificationCenter来实现观察者模式。 ```swift class Subject { var value: Int = 0 { didSet { NotificationCenter.default.post(name: Notification.Name("ValueDidUpdate"), object: nil) } } } class Observer { init() { NotificationCenter.default.addObserver(self, selector: #selector(valueDidUpdate), name: Notification.Name("ValueDidUpdate"), object: nil) } @objc func valueDidUpdate() { print("Value did update") } } let subject = Subject() let observer = Observer() subject.value = 5 ``` ### 6.3 面向对象编程的未来发展趋势 随着技术的发展和软件开发需求的变化,面向对象编程也在不断演化。一些趋势和发展方向包括函数式编程、响应式编程、声明式编程等。这些编程范式的结合能够帮助我们更好地应对复杂的软件开发需求,并提高代码的可维护性和性能。 总结: 在本章中,我们讨论了面向对象编程的最佳实践和常用设计模式在Swift中的应用。这些实践和模式可以帮助我们更好地组织和设计代码,提高代码的可读性和可维护性。此外,我们还探讨了面向对象编程的未来发展趋势,以便我们能够紧跟技术的进步并不断提升自己的编程能力。
corwn 最低0.47元/天 解锁专栏
买1年送1年
点击查看下一篇
profit 百万级 高质量VIP文章无限畅学
profit 千万级 优质资源任意下载
profit C知道 免费提问 ( 生成式Al产品 )

相关推荐

陆鲁

资深技术专家
超过10年工作经验的资深技术专家,曾在多家知名大型互联网公司担任重要职位。任职期间,参与并主导了多个重要的移动应用项目。
专栏简介
《iOS开发语言中的Swift语言》是一本全面介绍Swift语言的专栏,主要关注于iOS开发中使用Swift的各个方面。专栏中的第一篇文章是《Swift语言入门指南:基本语法和变量》,通过详细解释基本语法和变量的使用,帮助读者快速入门并理解Swift编程的基础知识。在这个专栏中,读者将深入了解Swift语言的特点和优势,学习如何使用Swift语言开发iOS应用程序。专栏将涵盖Swift语法、控制流、函数、面向对象编程等重要主题,并提供实际的代码示例和案例分析。无论是对于新手入门还是有经验的开发者,本专栏都将提供有益的指导和实用的技巧,帮助读者提高Swift编程的技能和效率。通过学习本专栏,读者将掌握Swift语言的精髓,并能够熟练运用Swift开发出高质量的iOS应用程序。无论是对于个人开发者还是职业开发者,本专栏都是提升iOS开发技能的不可或缺的指南。
最低0.47元/天 解锁专栏
买1年送1年
百万级 高质量VIP文章无限畅学
千万级 优质资源任意下载
C知道 免费提问 ( 生成式Al产品 )

最新推荐

【实时系统空间效率】:确保即时响应的内存管理技巧

![【实时系统空间效率】:确保即时响应的内存管理技巧](https://cdn.educba.com/academy/wp-content/uploads/2024/02/Real-Time-Operating-System.jpg) # 1. 实时系统的内存管理概念 在现代的计算技术中,实时系统凭借其对时间敏感性的要求和对确定性的追求,成为了不可或缺的一部分。实时系统在各个领域中发挥着巨大作用,比如航空航天、医疗设备、工业自动化等。实时系统要求事件的处理能够在确定的时间内完成,这就对系统的设计、实现和资源管理提出了独特的挑战,其中最为核心的是内存管理。 内存管理是操作系统的一个基本组成部

极端事件预测:如何构建有效的预测区间

![机器学习-预测区间(Prediction Interval)](https://d3caycb064h6u1.cloudfront.net/wp-content/uploads/2020/02/3-Layers-of-Neural-Network-Prediction-1-e1679054436378.jpg) # 1. 极端事件预测概述 极端事件预测是风险管理、城市规划、保险业、金融市场等领域不可或缺的技术。这些事件通常具有突发性和破坏性,例如自然灾害、金融市场崩盘或恐怖袭击等。准确预测这类事件不仅可挽救生命、保护财产,而且对于制定应对策略和减少损失至关重要。因此,研究人员和专业人士持

【算法竞赛中的复杂度控制】:在有限时间内求解的秘籍

![【算法竞赛中的复杂度控制】:在有限时间内求解的秘籍](https://dzone.com/storage/temp/13833772-contiguous-memory-locations.png) # 1. 算法竞赛中的时间与空间复杂度基础 ## 1.1 理解算法的性能指标 在算法竞赛中,时间复杂度和空间复杂度是衡量算法性能的两个基本指标。时间复杂度描述了算法运行时间随输入规模增长的趋势,而空间复杂度则反映了算法执行过程中所需的存储空间大小。理解这两个概念对优化算法性能至关重要。 ## 1.2 大O表示法的含义与应用 大O表示法是用于描述算法时间复杂度的一种方式。它关注的是算法运行时

时间序列分析的置信度应用:预测未来的秘密武器

![时间序列分析的置信度应用:预测未来的秘密武器](https://cdn-news.jin10.com/3ec220e5-ae2d-4e02-807d-1951d29868a5.png) # 1. 时间序列分析的理论基础 在数据科学和统计学中,时间序列分析是研究按照时间顺序排列的数据点集合的过程。通过对时间序列数据的分析,我们可以提取出有价值的信息,揭示数据随时间变化的规律,从而为预测未来趋势和做出决策提供依据。 ## 时间序列的定义 时间序列(Time Series)是一个按照时间顺序排列的观测值序列。这些观测值通常是一个变量在连续时间点的测量结果,可以是每秒的温度记录,每日的股票价

学习率对RNN训练的特殊考虑:循环网络的优化策略

![学习率对RNN训练的特殊考虑:循环网络的优化策略](https://img-blog.csdnimg.cn/20191008175634343.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MTYxMTA0NQ==,size_16,color_FFFFFF,t_70) # 1. 循环神经网络(RNN)基础 ## 循环神经网络简介 循环神经网络(RNN)是深度学习领域中处理序列数据的模型之一。由于其内部循环结

机器学习性能评估:时间复杂度在模型训练与预测中的重要性

![时间复杂度(Time Complexity)](https://ucc.alicdn.com/pic/developer-ecology/a9a3ddd177e14c6896cb674730dd3564.png) # 1. 机器学习性能评估概述 ## 1.1 机器学习的性能评估重要性 机器学习的性能评估是验证模型效果的关键步骤。它不仅帮助我们了解模型在未知数据上的表现,而且对于模型的优化和改进也至关重要。准确的评估可以确保模型的泛化能力,避免过拟合或欠拟合的问题。 ## 1.2 性能评估指标的选择 选择正确的性能评估指标对于不同类型的机器学习任务至关重要。例如,在分类任务中常用的指标有

Epochs调优的自动化方法

![ Epochs调优的自动化方法](https://img-blog.csdnimg.cn/e6f501b23b43423289ac4f19ec3cac8d.png) # 1. Epochs在机器学习中的重要性 机器学习是一门通过算法来让计算机系统从数据中学习并进行预测和决策的科学。在这一过程中,模型训练是核心步骤之一,而Epochs(迭代周期)是决定模型训练效率和效果的关键参数。理解Epochs的重要性,对于开发高效、准确的机器学习模型至关重要。 在后续章节中,我们将深入探讨Epochs的概念、如何选择合适值以及影响调优的因素,以及如何通过自动化方法和工具来优化Epochs的设置,从而

【批量大小与存储引擎】:不同数据库引擎下的优化考量

![【批量大小与存储引擎】:不同数据库引擎下的优化考量](https://opengraph.githubassets.com/af70d77741b46282aede9e523a7ac620fa8f2574f9292af0e2dcdb20f9878fb2/gabfl/pg-batch) # 1. 数据库批量操作的理论基础 数据库是现代信息系统的核心组件,而批量操作作为提升数据库性能的重要手段,对于IT专业人员来说是不可或缺的技能。理解批量操作的理论基础,有助于我们更好地掌握其实践应用,并优化性能。 ## 1.1 批量操作的定义和重要性 批量操作是指在数据库管理中,一次性执行多个数据操作命

【损失函数与随机梯度下降】:探索学习率对损失函数的影响,实现高效模型训练

![【损失函数与随机梯度下降】:探索学习率对损失函数的影响,实现高效模型训练](https://img-blog.csdnimg.cn/20210619170251934.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzQzNjc4MDA1,size_16,color_FFFFFF,t_70) # 1. 损失函数与随机梯度下降基础 在机器学习中,损失函数和随机梯度下降(SGD)是核心概念,它们共同决定着模型的训练过程和效果。本

激活函数理论与实践:从入门到高阶应用的全面教程

![激活函数理论与实践:从入门到高阶应用的全面教程](https://365datascience.com/resources/blog/thumb@1024_23xvejdoz92i-xavier-initialization-11.webp) # 1. 激活函数的基本概念 在神经网络中,激活函数扮演了至关重要的角色,它们是赋予网络学习能力的关键元素。本章将介绍激活函数的基础知识,为后续章节中对具体激活函数的探讨和应用打下坚实的基础。 ## 1.1 激活函数的定义 激活函数是神经网络中用于决定神经元是否被激活的数学函数。通过激活函数,神经网络可以捕捉到输入数据的非线性特征。在多层网络结构