|
|
|
@ -0,0 +1,76 @@
|
|
|
|
|
Java的函数和 C 类似,但因为Java是面向对象的语言,所以又有很多扩展的地方,我们这里主要对其特殊的地方进行讲解。
|
|
|
|
|
|
|
|
|
|
## 静态函数与非静态函数
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
到目前为止,我们学习的大多是静态函数。什么是静态函数?简单说来,静态函数是不依附对象就可以直接运行的函数。这个怎么解释?要了解静态与非静态函数的区别,首先需要知道什么是对象。前面说过,类是抽象描述的,如同类型定义;对象是类的一个真实变量(分配了具体的内存)。这种关系如果我们第一章的结构体指针类型和一个分配了存储空间的结构体指针变量。
|
|
|
|
|
|
|
|
|
|
### 如何计算字符串的长度
|
|
|
|
|
|
|
|
|
|
接下来看看C的函数的语义。函数是具备高度抽象的计算功能,需要传入参数后返回或者不返回结果(对数据进行修改)。例如C语言如果需要确定字符串的长度,这个函数的原型(签名)是这样的:
|
|
|
|
|
|
|
|
|
|
```C {.line-numbers}
|
|
|
|
|
int strlen(const char *str)
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
注意,C是非面向对象的,因此它需要知道需要计算哪个字符串的长度。
|
|
|
|
|
|
|
|
|
|
接下来,我们看看Java字符串长度的函数:
|
|
|
|
|
|
|
|
|
|
```java {.line-numbers}
|
|
|
|
|
String s = "Hello world!";
|
|
|
|
|
int size = s.length();
|
|
|
|
|
```
|
|
|
|
|
看到区别了吗?Java计算字符串长度的意思是计算自己本身字符串的长度;C是的含义是计算谁的字符串长度。这个就是最根本的区别。
|
|
|
|
|
|
|
|
|
|
对象是相关数据与在相关数据上操作函数的集合。
|
|
|
|
|
|
|
|
|
|
显然,s这个对象(String类型的实例),本身含有数据(字符串内容),以及相关的操作函数(例如 length 这个函数)。因此length()并不需要传入字符串的参数,因为length()在 s 这个对象上执行,s本身包含数据。
|
|
|
|
|
|
|
|
|
|
一般说来,需要在对象上执行的函数叫做非静态函数;而不需要对象,直接可以运行的函数叫做静态函数。其实,静态变量也是一样的,后面会做解释。
|
|
|
|
|
|
|
|
|
|
在前面几章中我们大多使用静态函数例如对基本类型(小写开头的类型,非类类型,非包装类型)操作的函数大多是静态函数。想一想为什么?因为基本类型尽量做到与C兼容,不是对象,需要静态函数来对基本类型进行操作。后面会学到基本类型的包装类型(warp类型),本生就是对象,因此可以直接在对象上进行操作。
|
|
|
|
|
|
|
|
|
|
想一想,前面学过那些静态函数?
|
|
|
|
|
|
|
|
|
|
前面章节也有例外,这些大写的类型都是类,一般都会实例化一个对象进行使用,例如:
|
|
|
|
|
|
|
|
|
|
1. String 类型
|
|
|
|
|
2. Scanner 类型
|
|
|
|
|
|
|
|
|
|
### Java与C语言像吗?
|
|
|
|
|
|
|
|
|
|
我们看看一个例子:
|
|
|
|
|
|
|
|
|
|
```java {.line-numbers}
|
|
|
|
|
public class Main {
|
|
|
|
|
static int size;
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
String s = "Hello world!";
|
|
|
|
|
size = s.length();
|
|
|
|
|
|
|
|
|
|
System.out.printf("String:'%s', size is %d.", s, size);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
上面这个例子,如果我们把类定义去掉后变成什么样子?
|
|
|
|
|
|
|
|
|
|
```java
|
|
|
|
|
static int size;
|
|
|
|
|
|
|
|
|
|
public static void main(String[] args) {
|
|
|
|
|
String s = "Hello world!";
|
|
|
|
|
size = s.length();
|
|
|
|
|
|
|
|
|
|
System.out.printf("String:'%s', size is %d.", s, size);
|
|
|
|
|
}
|
|
|
|
|
```
|
|
|
|
|
|
|
|
|
|
看看上面的例子,结构是不是非常像C语言?
|
|
|
|
|
|
|
|
|
|
思考一个问题:Java有全局变量吗?如果没有,如何实现全局变量?
|
|
|
|
|
如何调用一个静态的常量或者是变量?包是如何组织的?
|
|
|
|
|
|
|
|
|
|
其实,Java没有C那样的全局变量。因为Java所有的代码必须在一个类定义中(一个类在一个包中)。这样调用一个变量(必须是静态的),可以使用 xxx.yyy.Zzz.var 的方式进行调用。其中:xxx.yyy 是包定义,Zzz是类名,var是该类中的一个静态变量。同理,静态函数的调用也可以使用这种方式。这种方式在Java中叫做命名空间(name space),有什么好处?优势是所有的函数、变量、常量等都在一个空间中,不像C语言是全局的;这样即使是同名的变量、常量、函数,只要不再同一个空间中(也不可能在同一个空间中),那么就是合法的。通过空间的方式,相当于多了一个限定,不必给变量、常量、函数取很长的名字来进行区分。反观C语言,你们会看看很长的命名,因为都在全局中,需要保证命名的唯一性。
|