Decomposition,Abstraction and Functions
1. 编程中的基础语言机制(basic language mechanisms):
回顾我们已经学习的 Java 基本语法,包括:
• Primitives 原始数据类型(byte, short, int, long, float, double, boolean, char)
•complex expressions 复杂表达式
• branching 分支控制(if-else, if-else if, switch)
• iteration 循环控制(for, while, do-while)
这些基本构造可以实现任何计算任务,但要编写复杂且可维护的代码,还需要学习分解和抽象这两个核心概念。
2. 分解(Decomposition):
分解是指将一个复杂的程序问题拆解为若干个独立(self-contained parts)的小部分,每个部分都能完成一部分特定的计算,并且可以被其他程序重复使用。分解使得代码更加模块化、可读,并且易于调试。
分解的步骤:
• 将一个大问题拆分为多个子问题。
• 每个子问题只使用给定的输入和基本操作来完成任务,不依赖于其他外部部分。
举例了如何计算圆的面积,通过将计算过程分解为计算半径、使用 π 值、计算最终面积等子步骤。
3. 抽象(Abstraction):
抽象指的是忽略不必要的细节,只关注事物的功能。通过抽象,程序员可以将复杂的细节隐藏在背后,只展示其对外的接口。
将某物的功能与其实际执行方式分开(seperate)。
创建部分并抽象细节使我们能够在抑制细节(suppressing details)的同时编写复杂代码,这样我们就不会被这种复杂性所压倒(overwhelmed)。
4. 通过抽象实现分解:Abstraction Enables Decomposition
implementations is "opaque"不透明(or black an unknown)
抽象和分解的结合可以使程序更加模块化。每个模块都作为“黑箱”来处理,这意味着我们只需要知道模块的输入(inputs)和输出(outputs),而不需要了解它的内部实现(internal working)。这种方式在硬件和软件开发中广泛应用,通过接口来进行通信。
一个由许多不同公司设计和制造的复杂系统。系统中包含成百上千个独立的部分或组件,这些组件在不直接交流的情况下,通过事先定义好的规格(specification)和接口进行协作。每个组件的制造商需要了解其组件如何与其他组件相互作用(how its component interfaces to other components),但可以独立解决其部分问题(solve sub-problems independently),只要确保提供的输出符合规定的接口要求。这种模式既适用于硬件也适用于软件。
- 接口:接口是指组件之间的连接点,定义了组件如何互相交流信息和数据。
black box
- 隐藏繁琐的编码细节,不让用户看到
hide tedious coding details from the user - 在应用程序的不同部分重用黑盒,即无需复制和粘贴
reuse black box at different parties of the application(no copy and pasting) - 程序员创建细节,并设计界面
Coder creates details, and designs interface - 用户不需要也不希望看到这些细节
5. 函数(Function):
Also known as method or procedure in some programming languages
函数是一种用于实现分解和抽象的重要工具。
- 函数可以将一段代码封装为“黑箱”
capture code within a black box
并通过接口提供给其他部分调用。
函数的特点:
• 输入:函数可以接收一个或多个输入参数。
• 输出:函数通过返回值将计算结果传递给调用者。
• 黑箱操作:函数内部的实现细节对调用者隐藏,调用者只需要关心输入和输出。
例如,Math.abs() 函数用于返回一个数的绝对值,调用者只需要传入一个数并获取结果,而不需要了解如何具体计算。
Decomposition relies on abstraction to enable construction of
complex application from simpler functions
Javadoc是一种生成API文档的工具,它通过读取Java代码中的注释生成HTML格式的文档。这些注释通常使用特殊的标记
API文档会概述API(程序编程接口)的功能和用途,告诉开发者这个API能够解决什么问题。
函数的规范 (specification):
• 函数的行为是通过Javadoc(在Java中是推荐的文档注释格式)来描述的。Javadoc是一种可以生成API文档的注释格式,用于描述类、方法、参数、返回值等。
• 规范确保当用户提供满足条件的输入时,函数会根据规范产生输出。这也包括可能出现的副作用 (side effects),即函数可能会对外部状态产生影响。
示例代码:
/**
* Checks if the given character is alpha-numeric.
*
* @param ch the character to check
* @return true if the character is alpha-numeric; otherwise false.
*/
private boolean isAlphaNumeric(int ch) {
// do something and return the result
}
• @param 表示输入参数,@return 描述返回值。
• 这个函数的目的是检查给定的字符是否为字母或数字,返回布尔值。
函数的签名 (signature):
• 函数签名可以唯一标识(identified)一个函数,包括函数名、参数类型、参数数量等。通过函数签名,编译器可以区分同名的重载函数。
• 例如,函数 isAlphaNumeric(int ch) 的签名是:函数名为 isAlphaNumeric,参数类型为 int,参数名为 ch,返回类型为 boolean。
总结来说,这张图强调了通过规范来清楚描述函数行为的必要性,以及函数签名的重要性。在Java中,通过文档注释如Javadoc,可以为函数提供详细的说明,有助于提高代码的可读性和可维护性。
6. 函数的定义:
Defining a function
文档提供了函数的定义格式:
<修饰符> <返回类型> <函数名>(<参数>) {
// 函数体
return <结果>;
}
• <modifier>:修饰符,如 private 或 public,控制该方法的访问权限。private 表示该方法只能在该类内部使用。
• <return type>:返回类型,表示该方法返回的值的类型。在此例中,boolean 表示返回一个布尔值(true 或 false)。
• <function name>:方法的名称,在此例中是 isAlphaNumeric,表示这个方法是检查字符是否为字母或数字。
• <parameters>:方法的参数,在此例中是一个 int ch,表示要检查的字符作为输入。例如,isEven() 函数用于判断一个数字是否为偶数:
public boolean isEven(int num) {
int result = num % 2;
return result == 0;
}
make the code cleaner
public boolean isEven(int num) {
return num % 2 == 0;
}
• 当编写了一个函数后,Java 虚拟机(Java Virtual Machine)会把该函数加载到内存中,函数就可以在程序运行时被多次调用,而不需要重复编写代码。
7. 调用函数:
内部与外部函数
internal and external functions
• 内部函数:用户定义的函数。即程序员自己在代码中编写的函数。
• 外部函数:通常是来自外部库的函数,例如 JUnit 库(library)中包含的函数。它们通常被打包在 JAR 文件中,可以直接导入和使用。
• 所有 Java 函数必须定义在类中。(be declared within a class)
• 可以通过 类名.方法名(参数) 来调用类中的静态方法。
• 这是 Java 面向对象的设计,所有的代码都必须放在类的结构内。
- static 表示该方法是一个静态方法,可以不需要创建类的对象就可以直接通过类名调用。
- 举个例子,如果没有 static,你需要先创建类的实例(对象)来调用该方法:
Maths maths = new Maths();
System.out.println(maths.isEven(4)); // 通过对象调用
- 如果加上了 static 关键字,你可以直接通过类名来调用方法:
System.out.println(Maths.isEven(4)); // 直接通过类名调用
当调用函数时,Java 会根据传入的参数替换(substitute)函数定义中的形参,然后执行函数体,最后返回计算结果。
add all odd integers between a and b inclusively
int sumOfOdds(int a, int b) {
int sum = 0;
// Ensure 'a' starts from the first odd number
if (a % 2 == 0) {
a++;
}
// Iterate from 'a' to 'b', only considering odd numbers
for (int i = a; i <= b; i += 2) {
sum += i;
}
return sum;
}
(1) 函数调用的执行:
• 当Java执行一个函数调用时,它会创建一个新的“环境”envionment(也可以称为上下文context或作用域scope)。这个新环境就像一个迷你程序,它需要完成特定的任务。
• Java通过为每个函数调用创建一个新的独立环境,确保函数内部的变量与外部变量隔离,避免相互干扰。
• 函数内部的环境在函数执行结束后会消失,这样做保证了内存的有效管理。
(2) 全局环境与局部环境:
Global environment & Local environmenth
• 全局环境:是程序一开始运行时所在的默认环境,所有全局变量和函数都定义在全局环境中。
• 局部环境:每当调用一个函数时,Java会为该函数创建一个新的局部环境,这个环境独立于全局环境,是函数执行的上下文。
2. 函数调用的局部环境:
• 每次调用函数都会创建一个新的局部环境,这个环境只在函数内部有效,函数结束后,局部环境也会被销毁。
- 作用域(Scope):
作用域是指变量或函数在程序中可访问(accessibility)的范围。
1. 访问修饰符:
• Java 中有四种访问修饰符来控制变量和方法的可访问性:
• public:公开访问,任何地方都可以访问。
• protected:受保护访问,包内和子类中可访问,包外的其他类无法访问。
• 无修饰符:包级别访问,只能在同一个包内访问。
• private:私有访问,仅能在类内部访问。
9. 函数重载(Method Overloading):
called(or ran, invoked)
函数重载允许在同一个类中定义多个同名函数,但它们的参数类型或数量不同。通过这种方式,可以为不同的输入类型提供不同的实现。例如:
public boolean isEven(int num) {
return num % 2 == 0;
}
public boolean isEven(double num) {
return num % 2 == 0;
}
Signature:在编程中,函数的签名是指函数的名称加上它的参数类型和数量,而不包括返回类型。函数签名用于唯一地标识一个函数,确保在同一个作用域内没有其他函数与之冲突。
标签:Java,函数,int,num,return,boolean,111,Lecture From: https://blog.csdn.net/gyh101010/article/details/143048356