Java编程基础入门
发布时间: 2025-08-17 02:35:28 阅读量: 2 订阅数: 13 

### Java编程基础入门
#### 1. 引言
在踏上成为Java程序员的征程之前,理解面向对象编程(OOP)的基本术语和概念至关重要。这里主要是对这些概念进行初步介绍,后续会有更深入的探讨。Java支持编写多种可执行程序,如应用程序、小程序和Servlet。下面将介绍Java应用程序的基本元素,同时也会说明编译和运行Java应用程序的方法。
#### 2. 类
处理复杂问题的一个基本方法是进行抽象。抽象指的是对象区别于其他对象的本质属性和行为。面向对象编程的核心就是使用类和对象来对抽象进行建模,而难点在于找到合适的抽象。
类代表了一类对象,是创建对象的蓝图。类通过定义对象的属性和行为来对抽象进行建模。对象展现出其所属类定义的属性和行为。类中对象的属性也称为特性,在Java中由字段定义;字段是类中的变量,用于存储代表对象特定属性的值。类中对象的行为也称为操作,在Java中通过方法定义。类声明中的字段和方法统称为成员。
类为其对象提供的契约和实现之间有重要区别。契约定义了提供哪些服务,而实现则定义了类如何提供这些服务。客户端(即其他对象)只需了解对象的契约,而无需了解其实现,就可以使用该对象的服务。
下面以一个可以进行字符入栈和出栈操作的栈类为例。栈使用字符数组来存储字符,并使用一个字段来指示栈顶元素。使用统一建模语言(UML)符号,名为`CharStack`的类图形化表示如下:
```mermaid
classDiagram
class CharStack {
- char[] stackArray
- int topOfStack
+ CharStack(int capacity)
+ push(char element)
+ pop()
+ peek()
+ isEmpty()
+ isFull()
}
```
#### 2.1 声明成员:字段和方法
以下是`CharStack`类的声明示例,其目的是展示Java类声明的主要特征,而非栈的有效实现。
```java
//Source Filename: CharStack.java
public class CharStack {
// Fields:
private char[] stackArray; // The array implementing the stack.
private int topOfStack; // The top of the stack.
// Constructor:
public CharStack(int capacity) {
stackArray = new char[capacity];
topOfStack = -1;
}
// Methods:
public void push(char element) { stackArray[++topOfStack] = element; }
public char pop() { return stackArray[topOfStack--]; }
public char peek() { return stackArray[topOfStack]; }
public boolean isEmpty() { return topOfStack < 0; }
public boolean isFull() { return topOfStack == stackArray.length - 1; }
}
```
`CharStack`类有两个字段:
- `stackArray`:用于存储栈元素(字符)的数组。
- `topOfStack`:表示栈顶元素(即数组中最后一个存储字符的索引)。
该类还有五个方法,用于实现栈的基本操作:
- `push()`:将一个字符压入栈中。
- `pop()`:移除并返回栈顶元素。
- `peek()`:返回栈顶元素以供查看。
- `isEmpty()`:判断栈是否为空。
- `isFull()`:判断栈是否已满。
类声明中还有一个与类同名的类似方法的声明,称为构造函数。当从类创建对象时,构造函数会被执行。
#### 3. 对象
#### 3.1 类实例化、引用值和引用
从类创建对象的过程称为实例化。对象是类的一个实例,它以类为蓝图构建,是类所代表抽象的具体体现。在程序中使用对象之前,必须先创建它。
创建对象时会返回一个引用值,引用值表示一个特定的对象。对象引用(或简称引用)是一个可以存储引用值的变量。引用为对象提供了一个操作手段,因为它可以间接表示其引用值所指向的对象。在Java中,只能通过对象的引用值或持有该引用值的引用来操作对象。
创建对象通常涉及以下步骤:
1. **声明一个变量来存储对象的引用值**:声明一个合适类的引用变量来存储对象的引用值。
```java
// Declaration of two reference variables that will refer to
// two distinct objects, namely two stacks of characters, respectively.
CharStack stack1, stack2;
```
2. **创建对象**:使用`new`运算符结合构造函数调用来创建类的实例。
```java
// Create two distinct stacks of chars.
stack1 = new CharStack(10); // Stack length: 10 chars
stack2 = new CharStack(5); // Stack length: 5 chars
```
`new`运算符创建`CharStack`类的一个实例,并返回该实例的引用值。引用值可以赋值给合适类的引用变量,然后可以使用该引用变量来操作其引用值所存储的对象。每个对象都有其类声明中字段的独立副本。
对象的UML表示法如下:
```mermaid
classDiagram
class CharStack {
- char[] stackArray
- int topOfStack
+ CharStack(int capacity)
+ push(char element)
+ pop()
+ peek()
+ isEmpty()
+ isFull()
}
stack1:CharStack
stack2:CharStack
```
#### 3.2 对象别名
一个对象可以被多个引用引用,即这些引用存储了同一个对象的引用值,这样的引用称为别名。可以通过任何一个别名来操作对象,因为它们都指向同一个对象。
```java
// Create two distinct stacks of chars.
CharStack stackA = new CharStack(12); // Stack length: 12 chars
CharStack stackB = new CharStack(6); // Stack length: 6 chars
stackB = stackA; // (1) aliases after assignment
// The stack previously referenced by stackB can now be garbage collected.
```
在上述代码中,创建了两个栈。在赋值操作之前,`stackA`和`stackB`分别指向不同的栈;赋值操作后,`stackA`和`stackB`指向同一个栈。之前由`stackB`引用的栈现在可以被垃圾回收。Java的运行时系统会处理垃圾回收。
#### 4. 实例成员
每个创建的对象都有其类中定义字段的独立副本。对象的字段称为实例变量,对象中实例变量的值构成了其状态。如果两个不同对象的实例变量值相同,它们可以具有相同的状态。对象的方法定义了其行为,这些方法称为实例方法。需要注意的是,这些方法是针对类的每个对象的,而方法的实现是由类的所有实例共享的。
实例变量和实例方法统称为实例成员,以区别于仅属于类的静态成员。
#### 4.1 调用方法
对象通过消息传递进行通信。在Java中,通过使用二元中缀点(`.`)运算符调用对象的方法来实现。方法调用明确了完整的消息:消息的接收者对象、要调用的方法以及方法的参数(如果有)。被调用的方法也可以通过单个返回值将信息返回给调用者。调用的方法必须是为对象定义的,否则编译器会报错。
```java
CharStack stack = new CharStack(5); // Create a stack
stack.push('J'); // (1) Character 'J' pushed
char c = stack.pop(); // (2) One character popped and returned: 'J'
stack.printStackElements(); // (3) Compile-time error: No such method in CharStack
```
上述示例代码调用了`stack`引用所指向对象的方法。`push()`方法将一个字符压入栈中,`pop()`方法从栈中弹出一个字符。而尝试调用`printStackElements()`方法会导致编译时错误,因为`CharStack`类中没有定义该方法。
点(`.`)符号也可以用于通过引用访问对象的字段,但使用该符号受成员可访问性的限制。`CharStack`类中的字段具有私有可访问性,这意味着它们不能从类外部访问。
```java
stack.topOfStack++; // Compile-time error: topOfStack is a private field.
```
#### 5. 静态成员
在某些情况下,某些成员应该只属于类,而不属于从该类创建的任何对象。例如,当一个类想要跟踪创建了多少个该类的对象时,如果将计数器定义为类声明中的实例变量,每个对象都会有自己的计数器字段,无法解决计数问题。解决方案是将计数器字段声明为静态的,这样的字段称为静态变量,它属于类,而不属于类的任何对象。静态变量在类在运行时加载时初始化。类似地,类可以有属于类而不属于类的任何特定对象的静态方法。静态变量和静态方法统称为静态成员,使用`static`关键字声明。
以下是包含静态成员的`CharStack`类的示例:
```java
//Filename CharStack.java
public class CharStack {
// Instance variables:
private char[] stackArray; // The array implementing the stack.
private int topOfStack; // The top of the stack.
// Static variable
private static int counter;
// Constructor now increments the counter for each object created.
public CharStack(int capacity) {
stackArray = new char[capacity];
topOfStack = -1;
counter++;
}
// Instance methods:
public void push(char element) { stackArray[++topOfStack] = element; }
public char pop() { return stackArray[topOfStack--]; }
public char peek() { return stackArray[topOfStack]; }
public boolean isEmpty() { return topOfStack < 0; }
public boolean isFull() { return topOfStack == stackArray.length - 1; }
// Static method
public static int getInstanceCount() { return counter; }
}
```
类的成员分类如下表所示:
|成员类型|描述|访问方式|
| ---- | ---- | ---- |
|实例成员|对象的实例变量和实例方法,包括对象的属性和行为|只能通过对象引用访问或调用|
|静态成员|类的静态变量和静态方法|可以通过类名或对象引用访问或调用|
客户端可以使用类名来访问类中的静态成员:
```java
int count = CharStack.getInstanceCount(); // Class name to invoke static method
```
虽然也可以通过对象引用访问静态成员,但这被认为是不好的编程风格:
```java
CharStack stack1;
int count1 = stack1.getInstanceCount(); // Reference invokes static method
```
类中的静态成员可以通过类名和对象引用访问,而实例成员只能通过对象引用访问。
#### 6. 继承
从现有类构建新类有两种基本机制:继承和聚合。例如,从现有的`Vehicle`类继承来定义`Car`类是合理的,因为汽车是一种交通工具。`Vehicle`类有多个部分,因此定义一个由`Motor`、`Axle`和`GearBox`等类的对象组成的`Vehicle`类的复合对象也是合理的。
下面通过一个示例来说明继承。实现一个可以在终端打印其元素的字符栈。这个新栈具有`CharStack`类的所有属性和行为,还具有打印其元素的额外功能。由于这个可打印栈是字符栈,因此可以从`CharStack`类派生而来。这种关系如下所示:
```mermaid
classDiagram
class CharStack {
- char[] stackArray
- int topOfStack
+ CharStack(int capacity)
+ push(char element)
+ pop()
+ peek()
+ isEmpty()
+ isFull()
}
class PrintableCharStack {
+ printStackElements()
+ PrintableCharStack(int capacity)
}
CharStack <|-- PrintableCharStack
```
`PrintableCharStack`类称为子类,`CharStack`类称为超类。`CharStack`类是所有字符栈的通用表示,而`PrintableCharStack`类是可以打印其元素的字符栈的特殊表示。
在Java中,从现有类派生新类需要在子类声明中使用`extends`子句。子类只能扩展一个超类,并且可以继承超类的成员。以下代码片段实现了`PrintableCharStack`类:
```java
class PrintableCharStack extends CharStack {
// Instance method
public void printStackElements() {
for (int i = 0; i <= topOfStack; i++)
System.out.print(stackArray[i]); // print each char on terminal
System.out.println();
}
// The constructor calls the constructor of the superclass explicitly.
public PrintableCharStack(int capacity) { super(capacity); }
}
```
`PrintableCharStack`类扩展了`CharStack`类。实现`printStackElements()`方法需要访问超类`CharStack`的`stackArray`字段,但该字段是私有的,因此在子类中无法访问。如果将`CharStack`类中字段的可访问性更改为`protected`,子类就可以访问这些字段。
```java
// Source Filename: CharStack.java
public class CharStack {
// Instance variables
protected char[] stackArray; // The array that implements the stack.
protected int topOfStack; // The top of the stack.
// The rest of the definition is the same as in Example 1.2.
}
//Filename: PrintableCharStack.java
public class PrintableCharStack extends CharStack {
// Instance method
public void printStackElements() {
for (int i = 0; i <= topOfStack; i++)
System.out.print(stackArray[i]); // print each char on terminal
System.out.println();
}
// Constructor calls the constructor of the superclass explicitly.
PrintableCharStack(int capacity) { super(capacity); }
}
```
通过继承,`PrintableCharStack`类可以复用`CharStack`类的代码,并添加新的功能。
### Java编程基础入门
#### 7. 聚合
除了继承,聚合也是从现有类构建新类的重要机制。聚合体现的是整体与部分的关系,一个类的对象可以包含其他类的对象作为其组成部分。
例如,考虑一个`Vehicle`类,它代表交通工具。交通工具通常由多个部件组成,如发动机(`Motor`)、车轴(`Axle`)和变速箱(`GearBox`)等。我们可以通过聚合这些部件类的对象来构建`Vehicle`类。
以下是一个简单的示例代码:
```java
// Motor类
class Motor {
public void start() {
System.out.println("Motor started.");
}
}
// Axle类
class Axle {
public void rotate() {
System.out.println("Axle rotating.");
}
}
// GearBox类
class GearBox {
public void shiftGear() {
System.out.println("Gear shifted.");
}
}
// Vehicle类,通过聚合包含Motor、Axle和GearBox对象
class Vehicle {
private Motor motor;
private Axle axle;
private GearBox gearBox;
public Vehicle() {
motor = new Motor();
axle = new Axle();
gearBox = new GearBox();
}
public void operate() {
motor.start();
gearBox.shiftGear();
axle.rotate();
}
}
```
在上述代码中,`Vehicle`类聚合了`Motor`、`Axle`和`GearBox`类的对象。`Vehicle`类的`operate`方法调用了这些部件对象的方法,体现了整体与部分的协作关系。
#### 8. Java程序的编译和运行
学习Java编程,掌握如何编译和运行Java程序是必不可少的。以下是编译和运行Java程序的基本步骤:
##### 8.1 编写Java代码
首先,使用文本编辑器编写Java代码。例如,我们可以创建一个名为`HelloWorld.java`的文件,内容如下:
```java
public class HelloWorld {
public static void main(String[] args) {
System.out.println("Hello, World!");
}
}
```
##### 8.2 编译Java代码
打开命令行工具,导航到包含`HelloWorld.java`文件的目录。使用`javac`命令编译Java代码:
```sh
javac HelloWorld.java
```
如果代码没有错误,编译成功后会在同一目录下生成一个名为`HelloWorld.class`的字节码文件。
##### 8.3 运行Java程序
使用`java`命令运行编译后的Java程序:
```sh
java HelloWorld
```
运行上述命令后,控制台将输出`Hello, World!`。
#### 9. 总结与回顾
通过前面的介绍,我们对Java编程的基础知识有了较为全面的了解。下面通过一个表格总结本文涉及的重要概念:
|概念|描述|
| ---- | ---- |
|类|代表一类对象,是创建对象的蓝图,包含字段和方法|
|对象|类的实例,通过类实例化创建|
|实例成员|包括实例变量和实例方法,属于对象,每个对象有独立副本|
|静态成员|包括静态变量和静态方法,属于类,所有对象共享|
|继承|从现有类派生新类,子类可以继承超类的成员|
|聚合|一个类的对象包含其他类的对象作为组成部分,体现整体与部分的关系|
|编译和运行|使用`javac`命令编译Java代码,使用`java`命令运行编译后的程序|
为了更清晰地展示这些概念之间的关系,下面是一个mermaid格式的流程图:
```mermaid
graph LR
classDef process fill:#E5F6FF,stroke:#73A6FF,stroke-width:2px;
A(类):::process --> B(对象):::process
B --> C(实例成员):::process
A --> D(静态成员):::process
A --> E(继承):::process
A --> F(聚合):::process
G(Java代码):::process --> H(编译):::process
H --> I(运行):::process
```
#### 10. 实践建议
学习Java编程,实践是关键。以下是一些实践建议:
1. **多写代码**:通过编写各种类型的Java程序,加深对概念的理解和掌握。
2. **调试代码**:当程序出现错误时,学会使用调试工具找出问题所在,提高解决问题的能力。
3. **阅读优秀代码**:参考优秀的Java代码示例,学习他人的编程风格和技巧。
4. **参与开源项目**:参与开源项目可以与其他开发者交流合作,拓宽视野。
通过不断地实践和学习,相信你会逐渐掌握Java编程的精髓,成为一名优秀的Java程序员。
0
0
相关推荐









