Java面向对象编程基础:类、对象、方法与实例变量详解
立即解锁
发布时间: 2025-08-18 00:20:01 阅读量: 1 订阅数: 4 

### Java面向对象编程基础:类、对象、方法与实例变量详解
#### 1. 引言
在Java编程中,应用程序通常由多个类和方法组成。为了更好地组织和实现面向对象的应用程序,理解类、对象、方法和实例变量等基本概念至关重要。下面将通过实际例子详细介绍这些概念,并展示如何在Java中使用它们。
#### 2. 类、对象、方法和实例变量的概念
为了便于理解,我们以汽车为例。要驾驶汽车,首先需要有人设计它,就像设计房屋需要建筑图纸一样,汽车的设计图纸包含了加速踏板等部件的设计。加速踏板“隐藏”了使汽车加速的复杂机制,同样,刹车踏板和方向盘也“隐藏”了相应的机制,这使得不懂发动机原理的人也能轻松驾驶汽车。
在编程中,实现任务需要方法,方法描述了完成任务的机制,并对用户隐藏了复杂的实现细节。在Java中,我们创建类来容纳方法,就像汽车设计图纸容纳加速踏板的设计一样。一个类可以包含一个或多个方法,用于实现该类的任务。例如,一个表示银行账户的类可能包含存款、取款和查询余额的方法。
然而,就像不能驾驶汽车设计图纸一样,我们也不能直接“驾驶”类。必须从类创建对象,才能让程序执行类所描述的任务,这就是Java被称为面向对象编程语言的原因之一。当驾驶汽车时,踩下加速踏板相当于向汽车发送一个消息,要求它执行加速任务。类似地,向对象发送消息就是调用对象的方法,指示方法执行任务。
汽车除了具备各种功能外,还有许多属性,如颜色、车门数量、油箱中的汽油量、当前速度和行驶总里程等。这些属性在汽车设计图纸中有所体现,并且在驾驶过程中始终与汽车相关联。每个司机都知道自己汽车油箱中的汽油量,但不知道其他汽车油箱中的汽油量。同样,对象在程序中使用时也带有自己的属性,这些属性通过类中的实例变量来指定。
#### 3. 声明带有方法的类并实例化对象
下面通过一个具体的例子来说明如何声明带有方法的类并实例化对象。假设我们有两个类:`LibroCalificaciones`和`PruebaLibroCalificaciones`。
`LibroCalificaciones`类的代码如下:
```java
// Fig. 3.1: LibroCalificaciones.java
// Declaración de una clase con un método.
public class LibroCalificaciones {
// muestra un mensaje de bienvenida al usuario de LibroCalificaciones
public void mostrarMensaje() {
System.out.println( "Bienvenido al Libro de calificaciones!" );
} // fin del método mostrarMensaje
} // fin de la clase LibroCalificaciones
```
在这个类中,`mostrarMensaje`方法用于显示一条欢迎消息。类的声明以`public`关键字开头,这是一个访问修饰符,表示该类是公共的。每个类声明都包含`class`关键字,后面紧接着类名。方法的声明以`public`关键字开头,表示该方法是公共的,可以被其他类调用;`void`关键字表示该方法执行任务但不返回信息。
`PruebaLibroCalificaciones`类的代码如下:
```java
// Fig. 3.2: PruebaLibroCalificaciones.java
// Crea un objeto LibroCalificaciones y llama a su método mostrarMensaje.
public class PruebaLibroCalificaciones {
// el método main empieza la ejecución del programa
public static void main( String args[] ) {
// crea un objeto LibroCalificaciones y lo asigna a miLibroCalificaciones
LibroCalificaciones miLibroCalificaciones = new LibroCalificaciones();
// llama al método mostrarMensaje de miLibroCalificaciones
miLibroCalificaciones.mostrarMensaje();
} // fin de main
} // fin de la clase PruebaLibroCalificaciones
```
在这个类中,`main`方法是程序的入口点。通过`new`关键字创建`LibroCalificaciones`类的对象,并将其赋值给`miLibroCalificaciones`变量。然后调用`miLibroCalificaciones`对象的`mostrarMensaje`方法,显示欢迎消息。
要编译这个应用程序,可以使用以下命令:
```
javac LibroCalificaciones.java PruebaLibroCalificaciones.java
```
如果目录中只包含这个应用程序的文件,也可以使用以下命令编译所有类:
```
javac *.java
```
UML类图可以帮助我们可视化类的结构。`LibroCalificaciones`类的UML类图如下:
```mermaid
classDiagram
class LibroCalificaciones {
+ mostrarMensaje()
}
```
在UML类图中,类用矩形表示,分为三个部分。上部包含类名,中间部分包含类的属性(在这个例子中为空),下部包含类的操作(即方法)。操作名前的`+`号表示该操作是公共的。
#### 4. 声明带有参数的方法
在汽车的例子中,踩下加速踏板向汽车发送加速消息时,还包含了额外的信息,即踏板的踩踏程度,这决定了汽车的加速速度。在编程中,方法可能需要一个或多个参数来表示执行任务所需的额外信息。调用方法时,需要为方法的每个参数提供值(称为参数)。
下面是一个带有参数的方法的例子。`LibroCalificaciones`类的代码如下:
```java
// Fig. 3.4: LibroCalificaciones.java
// Declaración de una clase con un método que tiene un parámetro.
public class LibroCalificaciones {
// muestra un mensaje de bienvenida al usuario de LibroCalificaciones
public void mostrarMensaje( String nombreDelCurso ) {
System.out.printf( "Bienvenido al libro de calificaciones para\n%s!\n", nombreDelCurso );
} // fin del método mostrarMensaje
} // fin de la clase LibroCalificaciones
```
在这个类中,`mostrarMensaje`方法接受一个`String`类型的参数`nombreDelCurso`,用于表示课程名称。方法内部使用`printf`方法显示包含课程名称的欢迎消息。
`PruebaLibroCalificaciones`类的代码如下:
```java
// Fig. 3.5: PruebaLibroCalificaciones.java
// Crea un objeto LibroCalificaciones y pasa un objeto String
// a su método mostrarMensaje.
import java.util.Scanner; // el programa usa la clase Scanner
public class PruebaLibroCalificaciones {
// el método main empieza la ejecución del programa
public static void main( String args[] ) {
// crea un objeto Scanner para obtener la entrada de la ventana de comandos
Scanner entrada = new Scanner( System.in );
// crea un objeto LibroCalificaciones y lo asigna a miLibroCalificaciones
LibroCalificaciones miLibroCalificaciones = new LibroCalificaciones();
// pide y recibe el nombre del curso como entrada
System.out.println( "Escriba el nombre del curso:" );
String nombreDelCurso = entrada.nextLine(); // lee una línea de texto
System.out.println(); // imprime una línea en blanco
// llama al método mostrarMensaje de miLibroCalificaciones
// y pasa nombreDelCurso como argumento
miLibroCalificaciones.mostrarMensaje( nombreDelCurso );
} // fin de main
} // fin de la clase PruebaLibroCalificaciones
```
在这个类中,`main`方法使用`Scanner`类获取用户输入的课程名称,然后将其作为参数传递给`miLibroCalificaciones`对象的`mostrarMensaje`方法。
声明方法时,需要在方法名后的括号内指定参数列表。每个参数必须指定类型和标识符。调用方法时,传递的参数值将被分配给方法参数。方法内部使用参数来访问传递的值。
UML类图可以更新为显示带有参数的方法。`LibroCalificaciones`类的更新后的UML类图如下:
```mermaid
classDiagram
class LibroCalificaciones {
+ mostrarMensaje( nombreDelCurso : String )
}
```
在UML类图中,参数的表示方式是在操作名后的括号内列出参数名,后面跟着冒号和参数类型。
#### 5. 实例变量、设置方法和获取方法
在之前的例子中,我们在`main`方法中声明了所有变量。这些在特定方法体内声明的变量称为局部变量,只能在该方法中使用。当方法结束时,局部变量的值会丢失。
在编程中,对象在程序中使用时带有自己的属性。这些属性通过类中的实例变量来表示。实例变量在类的声明中声明,但在类的方法体之外。每个类的对象都有自己独立的实例变量副本。
下面是一个包含实例变量、设置方法和获取方法的例子。`LibroCalificaciones`类的代码如下:
```java
// Fig. 3.7: LibroCalificaciones.java
// Clase LibroCalificaciones que contiene una variable de instancia nombreDelCurso
// y métodos para establecer y obtener su valor.
public class LibroCalificaciones {
private String nombreDelCurso; // nombre del curso para este LibroCalificaciones
// método para establecer el nombre del curso
public void establecerNombreDelCurso( String nombre ) {
nombreDelCurso = nombre; // almacena el nombre del curso
} // fin del método establecerNombreDelCurso
// método para obtener el nombre del curso
public String obtenerNombreDelCurso() {
return nombreDelCurso;
} // fin del método obtenerNombreDelCurso
// muestra un mensaje de bienvenida al usuario de LibroCalificaciones
public void mostrarMensaje() {
// esta instrucción llama a obtenerNombreDelCurso para obtener el
// nombre del curso que representa este LibroCalificaciones
System.out.printf( "Bienvenido al libro de calificaciones para\n%s!\n", obtenerNombreDelCurso() );
} // fin del método mostrarMensaje
} // fin de la clase LibroCalificaciones
```
在这个类中,`nombreDelCurso`是一个`private`类型的实例变量,表示课程名称。`establecerNombreDelCurso`方法用于设置课程名称,`obtenerNombreDelCurso`方法用于获取课程名称。`mostrarMensaje`方法调用`obtenerNombreDelCurso`方法获取课程名称,并显示包含课程名称的欢迎消息。
`PruebaLibroCalificaciones`类的代码如下:
```java
// Fig. 3.8: PruebaLibroCalificaciones.java
// Crea y manipula un objeto LibroCalificaciones.
import java.util.Scanner; // el programa usa la clase Scanner
public class PruebaLibroCalificaciones {
// el método main empieza la ejecución del programa
public static void main( String args[] ) {
// crea un objeto Scanner para obtener la entrada de la ventana de comandos
Scanner entrada = new Scanner( System.in );
// crea un objeto LibroCalificaciones y lo asigna a miLibroCalificaciones
LibroCalificaciones miLibroCalificaciones = new LibroCalificaciones();
// muestra el valor inicial de nombreDelCurso
System.out.printf( "El nombre inicial del curso es: %s\n\n", miLibroCalificaciones.obtenerNombreDelCurso() );
// pide y lee el nombre del curso
System.out.println( "Escriba el nombre del curso:" );
String elNombre = entrada.nextLine(); // lee una línea de texto
miLibroCalificaciones.establecerNombreDelCurso( elNombre ); // establece el nombre del curso
System.out.println(); // imprime una línea en blanco
// muestra el mensaje de bienvenida después de especificar el nombre del curso
miLibroCalificaciones.mostrarMensaje();
} // fin de main
} // fin de la clase PruebaLibroCalificaciones
```
在这个类中,`main`方法创建`LibroCalificaciones`类的对象,并调用`obtenerNombreDelCurso`方法显示初始课程名称(初始值为`null`)。然后获取用户输入的课程名称,调用`establecerNombreDelCurso`方法设置课程名称,最后调用`mostrarMensaje`方法显示包含课程名称的欢迎消息。
通常,类的实例变量声明为`private`,以实现数据隐藏。客户端通过公共的设置方法和获取方法来操作私有实例变量。
UML类图可以显示类的实例变量和方法。`LibroCalificaciones`类的UML类图如下:
```mermaid
classDiagram
class LibroCalificaciones {
- nombreDelCurso : String
+ establecerNombreDelCurso( nombre : String )
+ obtenerNombreDelCurso() : String
+ mostrarMensaje()
}
```
在UML类图中,实例变量用负号`-`表示其为私有属性,方法名前的`+`号表示该方法是公共的。可以通过冒号指定方法的返回类型。
#### 6. 基本类型和引用类型的比较
Java中的数据类型分为基本类型和引用类型。基本类型包括`boolean`、`byte`、`char`、`short`、`int`、`long`、`float`和`double`。所有非基本类型都是引用类型,类所指定的对象类型就是引用类型。
基本类型的变量一次只能存储一个其声明类型的值。例如,`int`类型的变量一次只能存储一个整数。基本类型的实例变量会默认初始化,`byte`、`char`、`short`、`int`、`long`、`float`和`double`类型的变量初始化为0,`boolean`类型的变量初始化为`false`。可以为基本类型的变量指定自己的初始值。需要注意的是,局部变量不会默认初始化,任何尝试使用未初始化的局部变量都会导致编译错误。
程序使用引用类型的变量(通常称为引用)来存储对象在计算机内存中的位置。引用变量指向程序中的对象,每个被引用的对象可以包含多个实例变量和方法。引用类型的实例变量默认初始化为`null`,表示“无引用”。
例如,在之前的例子中,`miLibroCalificaciones`是一个引用类型的变量,它指向`LibroCalificaciones`类的对象。通过引用变量可以调用对象的方法,但基本类型的变量不能引用对象,因此不能用于调用方法。
#### 7. 使用构造函数初始化对象
当创建`LibroCalificaciones`类的对象时,如果没有指定构造函数,其实例变量会默认初始化为`null`。如果希望在创建对象时为课程名称提供初始值,可以为类提供构造函数。
构造函数是一种特殊的方法,用于在创建对象时初始化对象。构造函数的名称必须与类名相同,并且不能指定返回类型(甚至不能是`void`)。Java要求为每个创建的对象调用构造函数。使用`new`关键字创建对象时,会调用类的构造函数进行初始化。
下面是一个包含构造函数的`LibroCalificaciones`类的例子:
```java
// Fig. 3.10: LibroCalificaciones.java
// La clase LibroCalificaciones con un constructor para inicializar el nombre del curso.
public class LibroCalificaciones {
private String nombreDelCurso; // nombre del curso para este LibroCalificaciones
// el constructor inicializa nombreDelCurso con el objeto String que se provee como argumento
public LibroCalificaciones( String nombre ) {
nombreDelCurso = nombre; // inicializa nombreDelCurso
} // fin del constructor
// método para establecer el nombre del curso
public void establecerNombreDelCurso( String nombre ) {
nombreDelCurso = nombre; // almacena el nombre del curso
} // fin del método establecerNombreDelCurso
// método para obtener el nombre del curso
public String obtenerNombreDelCurso() {
return nombreDelCurso;
} // fin del método obtenerNombreDelCurso
// muestra un mensaje de bienvenida al usuario de LibroCalificaciones
public void mostrarMensaje() {
// esta instrucción llama a obtenerNombreDelCurso para obtener el
// nombre del curso que este LibroCalificaciones representa
System.out.printf( "Bienvenido al Libro de calificaciones para\n%s!\n", obtenerNombreDelCurso() );
} // fin del método mostrarMensaje
} // fin de la clase LibroCalificaciones
```
在这个类中,构造函数`LibroCalificaciones`接受一个`String`类型的参数`nombre`,并将其赋值给实例变量`nombreDelCurso`。
下面是使用该构造函数初始化对象的例子:
```java
// Fig. 3.11: PruebaLibroCalificaciones.java
// El constructor de LibroCalificaciones se utiliza para especificar el
// nombre del curso cada vez que se crea cada objeto LibroCalificaciones.
public class PruebaLibroCalificaciones {
// el método main empieza la ejecución del programa
public static void main( String args[] ) {
// crea objeto LibroCalificaciones
LibroCalificaciones libroCalificaciones1 = new LibroCalificaciones(
"CS101 Introduccion a la programacion en Java" );
LibroCalificaciones libroCalificaciones2 = new LibroCalificaciones(
"CS102 Estructuras de datos en Java" );
// muestra el valor inicial de nombreDelCurso para cada LibroCalificaciones
System.out.printf( "El nombre del curso de libroCalificaciones1 es: %s\n",
libroCalificaciones1.obtenerNombreDelCurso() );
System.out.printf( "El nombre del curso de libroCalificaciones2 es: %s\n",
libroCalificaciones2.obtenerNombreDelCurso() );
} // fin de main
} // fin de la clase PruebaLibroCalificaciones
```
在这个类中,`main`方法创建了两个`LibroCalificaciones`类的对象,并分别使用不同的参数调用构造函数进行初始化。然后调用`obtenerNombreDelCurso`方法显示每个对象的课程名称。
如果一个类没有显式提供构造函数,编译器会提供一个无参数的默认构造函数。当一个类只有默认构造函数时,其实例变量会初始化为默认值。如果为类声明了一个或多个构造函数,Java编译器将不会为该类创建默认构造函数。
UML类图可以显示类的构造函数。`LibroCalificaciones`类的UML类图如下:
```mermaid
classDiagram
class LibroCalificaciones {
- nombreDelCurso : String
«constructor» LibroCalificaciones( nombre : String )
+ establecerNombreDelCurso( nombre : String )
+ obtenerNombreDelCurso() : String
+ mostrarMensaje()
}
```
在UML类图中,构造函数用`«constructor»`表示,放在方法列表的前面。
#### 8. 浮点数和`double`类型
在很多应用中,如银行账户的余额,通常不是整数,而是包含小数点的浮点数。Java提供了两种基本类型来存储浮点数:`float`和`double`。
`float`类型的变量表示单精度浮点数,具有七位有效数字。`double`类型的变量表示双精度浮点数,需要的内存是`float`类型的两倍,提供15位有效数字,精度大约是`float`类型的两倍。对于大多数程序所需的值范围,`float`类型的变量通常就足够了,但为了保险起见,我们可以使用`double`类型的变量。实际上,Java默认将代码中编写的所有浮点数(如`7.33`和`0.0975`)视为`double`类型的值,这些代码中的值称为浮点字面量。
下面是一个表示银行账户的`Cuenta`类的例子:
```java
// Fig. 3.13: Cuenta.java
// La clase Cuenta con un constructor para
// inicializar la variable de instancia saldo.
public class Cuenta {
private double saldo; // variable de instancia que almacena el saldo
// constructor
public Cuenta( double saldoInicial ) {
// valida que saldoInicial sea mayor que 0.0;
// si no lo es, saldo se inicializa con el valor predeterminado 0.0
if ( saldoInicial > 0.0 )
saldo = saldoInicial;
} // fin del constructor de Cuenta
// abona (suma) un monto a la cuenta
public void abonar( double monto ) {
saldo = saldo + monto; // suma el monto al saldo
} // fin del método abonar
// devuelve el saldo de la cuenta
public double obtenerSaldo() {
return saldo; // proporciona el valor de saldo al método que hizo la llamada
} // fin del método obtenerSaldo
} // fin de la clase Cuenta
```
在这个类中,`saldo`是一个`double`类型的实例变量,表示账户余额。构造函数接受一个`double`类型的参数`saldoInicial`,用于初始化账户余额。如果`saldoInicial`大于0.0,则将其赋值给`saldo`,否则`saldo`初始化为默认值0.0。`abonar`方法用于向账户中存款,`obtenerSaldo`方法用于获取账户余额。
下面是使用`Cuenta`类的例子:
```java
// Fig. 3.14: PruebaCuenta.java
// Entrada y salida de números de punto flotante con objetos Cuenta.
import java.util.Scanner;
public class PruebaCuenta {
// el método main empieza la ejecución de la aplicación de Java
public static void main( String args[] ) {
Cuenta cuenta1 = new Cuenta( 50.00 ); // crea objeto Cuenta
Cuenta cuenta2 = new Cuenta( -7.53 ); // crea objeto Cuenta
// muestra el saldo inicial de cada objeto
System.out.printf( "Saldo de cuenta1: $%.2f\n", cuenta1.obtenerSaldo() );
System.out.printf( "Saldo de cuenta2: $%.2f\n\n", cuenta2.obtenerSaldo() );
// crea objeto Scanner para obtener la entrada de la ventana de comandos
Scanner entrada = new Scanner( System.in );
double montoDeposito; // deposita el monto escrito por el usuario
System.out.print( "Escriba el monto a depositar para cuenta1: " ); // indicador
montoDeposito = entrada.nextDouble(); // obtiene entrada del usuario
System.out.printf( "\nsumando %.2f al saldo de cuenta1\n\n", montoDeposito );
cuenta1.abonar( montoDeposito ); // suma al saldo de cuenta1
// muestra los saldos
System.out.printf( "Saldo de cuenta1: $%.2f\n", cuenta1.obtenerSaldo() );
System.out.printf( "Saldo de cuenta2: $%.2f\n\n", cuenta2.obtenerSaldo() );
System.out.print( "Escriba el monto a depositar para cuenta2: " ); // indicador
montoDeposito = entrada.nextDouble(); // obtiene entrada del usuario
System.out.printf( "\nsumando %.2f al saldo de cuenta2\n\n", montoDeposito );
cuenta2.abonar( montoDeposito ); // suma al saldo de cuenta2
// muestra los saldos
System.out.printf( "Saldo de cuenta1: $%.2f\n", cuenta1.obtenerSaldo() );
System.out.printf( "Saldo de cuenta2: $%.2f\n", cuenta2.obtenerSaldo() );
} // fin de main
} // fin de la clase PruebaCuenta
```
在这个类中,`main`方法创建了两个`Cuenta`类的对象,并分别使用不同的参数调用构造函数进行初始化。然后显示每个对象的初始余额。通过`Scanner`类获取用户输入的存款金额,调用`abonar`方法将存款金额添加到账户余额中,最后再次显示每个对象的余额。
在格式化输出浮点数时,可以使用`%f`格式说明符。可以在`%`和`f`之间指定精度,表示小数点后要显示的位数。例如,`%.2f`表示显示小数点后两位。
UML类图可以显示`Cuenta`类的结构。`Cuenta`类的UML类图如下:
```mermaid
classDiagram
class Cuenta {
- balance : Double
«constructor» Cuenta( saldoInicial : Double )
+ abonar( monto : Double )
+ obtenerSaldo() : Double
}
```
在UML类图中,`balance`表示账户余额,是私有属性。构造函数和方法的参数和返回类型都用相应的UML类型表示。
#### 9. (可选)GUI和图形的实际示例:使用对话框
许多应用程序使用窗口或对话框来显示输出,而不是在命令窗口中显示。`JOptionPane`类提供了预打包的对话框,用于显示包含消息的窗口,称为消息对话框。
下面是一个显示消息对话框的例子:
```java
// Fig. 3.17: Dialogo1.java
// Imprimir varias líneas en un cuadro de diálogo.
import javax.swing.JOptionPane; // importa la clase JOptionPane
public class Dialogo1 {
public static void main( String args[] ) {
// muestra un cuadro de diálogo con un mensaje
JOptionPane.showMessageDialog( null, "Bienvenido\na\nJava" );
} // fin de main
} // fin de la clase Dialogo1
```
在这个类中,`main`方法调用`JOptionPane`类的`showMessageDialog`方法,显示一个包含多行消息的对话框。`showMessageDialog`方法需要两个参数,第一个参数帮助Java确定对话框的位置,当为`null`时,对话框将显示在计算机屏幕的中心;第二个参数是要在对话框中显示的消息。
还可以使用`JOptionPane`类的`showInputDialog`方法创建输入对话框,允许用户输入数据。下面是一个获取用户输入并显示欢迎消息的例子:
```java
// Fig. 3.18: DialogoNombre.java
// Entrada básica con un cuadro de diálogo.
import javax.swing.JOptionPane;
public class DialogoNombre {
public static void main( String args[] ) {
// pide al usuario que escriba su nombre
String nombre = JOptionPane.showInputDialog( "Cual es su nombre?" );
// crea el mensaje
String mensaje = String.format( "Bienvenido, %s, a la programacion en Java!", nombre );
// muestra el mensaje para dar la bienvenida al usuario por su nombre
JOptionPane.showMessageDialog( null, mensaje );
} // fin de main
} // fin de la clase DialogoNombre
```
在这个类中,`main`方法调用`showInputDialog`方法显示一个输入对话框,提示用户输入姓名。用户输入姓名后,点击“确定”按钮或按下回车键,方法返回用户输入的字符串。然后使用`String.format`方法创建包含用户姓名的欢迎消息,并调用`showMessageDialog`方法显示欢迎消息对话框。
#### 10. (可选)软件工程的实际示例:在需求文档中识别类
在设计系统时,需要从需求文档中识别出必要的类。以设计ATM系统为例,首先需要分析需求文档中的名词和名词短语,以确定构成系统的类。
在ATM系统的需求文档中,识别出的名词和名词短语包括银行、ATM、用户、客户、交易、账户、余额、资金、屏幕、数字键盘、现金 dispenser、20美元纸币、存款槽、存款信封、账户号码、NIP、银行数据库、余额查询、取款、存款等。
然而,并非所有这些名词和名词短语都需要建模为类。例如,银行不是ATM系统的一部分,不需要将其建模为类;客户和用户是与系统交互的外部实体,也不需要在ATM软件中建模为类。同样,20美元纸币和存款信封是现实世界中的物理对象,不需要在自动化系统中建模为类,可以通过相关类的属性来表示它们的存在。
在简化的ATM系统中,将余额等金额表示为类的属性是合适的。账户号码和NIP是银行账户的重要信息,是账户类的重要属性,但它们不展示行为,因此可以将它们建模为账户类的属性。
通常,需求文档中描述的“交易”是一个广义的概念,在当前阶段,我们将三种类型的交易(余额查询、取款和存款)分别建模为单独的类。这些类具有执行各自交易所需的特定属性和行为。例如,取款需要知道用户要提取的金额,而余额查询不需要额外的数据。
根据剩余的名词和名词短语,确定需要在系统中实现的类包括ATM、屏幕、数字键盘、现金 dispenser、存款槽、账户、银行数据库、余额查询、取款和存款。
UML类图可以帮助我们可视化这些类及其之间的关系。例如,下面是一个简化的ATM系统类图:
```mermaid
classDiagram
class ATM {
}
class Pantalla {
}
class Teclado {
}
class DispensadorEfectivo {
}
class RanuraDeposito {
}
class Cuenta {
}
class BaseDatosBanco {
}
class SolicitudSaldo {
}
class Retiro {
}
class Deposito {
}
ATM "1" -- "1" Pantalla : tiene una
ATM "1" -- "1" Teclado : tiene una
ATM "1" -- "1" DispensadorEfectivo : tiene una
ATM "1" -- "1" RanuraDeposito : tiene una
ATM "1" -- "1" BaseDatosBanco : autentica al usuario en base a
BaseDatosBanco "1" -- "0..*" Cuenta : contiene
Retiro "1" -- "1" ATM : Ejecuta
Retiro "1" -- "1" BaseDatosBanco : Accede a/modifica el saldo de una cuenta a través de
Retiro "1" -- "1" Pantalla : utiliza
Retiro "1" -- "1" Teclado : utiliza
Retiro "1" -- "1" DispensadorEfectivo : utiliza
```
在这个类图中,类之间的连线表示它们之间的关联关系,连线上的数字表示关联的多重性。例如,一个ATM对象与一个屏幕对象、一个数字键盘对象、一个现金 dispenser对象和一个存款槽对象相关联,表示ATM“有一个”屏幕、数字键盘、现金 dispenser和存款槽。一个ATM对象通过银行数据库对象来验证用户身份。银行数据库对象可以包含多个账户对象。取款交易对象与ATM对象、银行数据库对象、屏幕对象、数字键盘对象和现金 dispenser对象相关联,表示取款交易需要使用这些对象来完成。
通过识别类和建模类之间的关系,可以更好地理解系统的结构,为后续的开发工作奠定基础。
#### 总结
通过本文的介绍,我们学习了Java中类、对象、方法和实例变量的基本概念。了解了如何声明类、方法和实例变量,如何创建对象并调用对象的方法,以及如何使用构造函数初始化对象。还学习了基本类型和引用类型的区别,以及如何处理浮点数和使用对话框进行用户交互。此外,通过软件工程的实际示例,学习了如何从需求文档中识别类并建模类之间的关系。这些知识将在大多数Java应用程序的开发中发挥重要作用。在后续的学习中,我们将开始介绍控制语句,用于指定程序中操作的执行顺序。
### Java面向对象编程基础:类、对象、方法与实例变量详解
#### 11. 关键概念总结
为了更好地回顾前面所讲的内容,下面通过表格的形式对一些关键概念进行总结:
| 概念 | 描述 |
| --- | --- |
| 类 | 程序中容纳方法的单元,可包含一个或多个用于实现类任务的方法 |
| 对象 | 类的实例,通过类创建,Java是面向对象编程语言,需创建对象执行类描述的任务 |
| 方法 | 实现任务的代码块,隐藏实现细节,可接收参数、返回结果 |
| 实例变量 | 类中声明但在方法体外的变量,每个对象有独立副本,用于表示对象属性 |
| 构造函数 | 特殊方法,与类名相同,无返回类型,用于创建对象时初始化对象 |
| 基本类型 | 包括`boolean`、`byte`、`char`、`short`、`int`、`long`、`float`、`double`,一次存一个声明类型的值 |
| 引用类型 | 类指定的对象类型,变量存对象内存位置,默认初始化为`null` |
#### 12. 常见错误与注意事项
在Java编程过程中,有一些常见错误需要我们特别注意:
- **方法调用错误**:调用方法时,参数数量和类型必须与方法声明一致,否则会导致编译错误。例如:
```java
public class ErrorExample {
public void methodWithParam(int num) {
System.out.println(num);
}
public static void main(String[] args) {
ErrorExample example = new ErrorExample();
// 错误:参数数量不匹配
// example.methodWithParam();
// 错误:参数类型不匹配
// example.methodWithParam("abc");
example.methodWithParam(10); // 正确
}
}
```
- **未初始化变量**:局部变量不会默认初始化,使用未初始化的局部变量会导致编译错误。示例如下:
```java
public class UninitializedVariableExample {
public static void main(String[] args) {
int num;
// 错误:使用未初始化的局部变量
// System.out.println(num);
num = 20;
System.out.println(num); // 正确
}
}
```
- **类文件命名错误**:以`public`关键字开头的类声明,必须存储在与类名完全相同且以`.java`为扩展名的文件中,否则会编译失败。
#### 13. 代码优化建议
为了提高代码的可读性和可维护性,我们可以遵循以下优化建议:
- **合理使用访问修饰符**:将实例变量声明为`private`,通过公共的设置方法和获取方法操作,实现数据隐藏和封装。例如:
```java
public class OptimizedClass {
private int value;
public void setValue(int value) {
this.value = value;
}
public int getValue() {
return value;
}
}
```
- **方法命名规范**:方法名遵循首字母小写,后续单词首字母大写的命名约定,提高代码可读性。
- **添加注释**:在关键代码处添加注释,解释代码的功能和用途,方便自己和他人理解代码。例如:
```java
// 计算两个整数的和
public int add(int a, int b) {
return a + b;
}
```
#### 14. 实际应用场景拓展
Java面向对象编程的概念在很多实际场景中都有广泛应用,以下是一些拓展场景:
- **游戏开发**:在游戏中,每个角色、道具等都可以抽象为一个类。例如,一个简单的角色扮演游戏中,角色类可以有以下代码:
```java
public class Character {
private String name;
private int health;
private int attack;
public Character(String name, int health, int attack) {
this.name = name;
this.health = health;
this.attack = attack;
}
public void attack(Character target) {
target.health -= this.attack;
System.out.println(this.name + " 攻击了 " + target.name + "," + target.name + " 剩余血量: " + target.health);
}
}
```
可以使用以下代码进行测试:
```java
public class GameTest {
public static void main(String[] args) {
Character hero = new Character("英雄", 100, 20);
Character monster = new Character("怪物", 80, 15);
hero.attack(monster);
}
}
```
- **电商系统**:商品、订单、用户等都可以用类来表示。以下是一个简单的商品类示例:
```java
public class Product {
private String name;
private double price;
private int stock;
public Product(String name, double price, int stock) {
this.name = name;
this.price = price;
this.stock = stock;
}
public void reduceStock(int quantity) {
if (stock >= quantity) {
stock -= quantity;
System.out.println("成功购买 " + quantity + " 件 " + name + ",剩余库存: " + stock);
} else {
System.out.println("库存不足,无法购买");
}
}
}
```
测试代码如下:
```java
public class EcommerceTest {
public static void main(String[] args) {
Product product = new Product("手机", 5000, 10);
product.reduceStock(3);
}
}
```
#### 15. 流程图回顾
下面通过mermaid流程图来回顾创建对象并调用方法的流程:
```mermaid
graph TD;
A[定义类] --> B[创建对象];
B --> C[调用构造函数初始化对象];
C --> D[调用对象方法];
D --> E{方法是否需要参数};
E -- 是 --> F[传递参数];
E -- 否 --> G[执行方法];
F --> G;
G --> H{方法是否有返回值};
H -- 是 --> I[接收返回值];
H -- 否 --> J[方法执行结束];
I --> J;
```
#### 16. 总结与展望
通过前面的学习,我们深入了解了Java面向对象编程的基础概念,包括类、对象、方法、实例变量、构造函数等,掌握了基本类型和引用类型的区别,学会了使用对话框进行用户交互,以及从需求文档中识别类和建模类之间的关系。这些知识是Java编程的基石,在后续的开发中会经常用到。
在未来的学习中,我们将进一步探索Java的高级特性,如继承、多态、异常处理等,这些特性将使我们能够开发出更加复杂、强大的Java应用程序。同时,我们还将学习如何使用控制语句来精确控制程序的执行流程,提高程序的逻辑性和灵活性。
希望大家能够不断实践,加深对这些知识的理解和掌握,在Java编程的道路上越走越远。
以上就是关于Java面向对象编程基础的详细介绍,希望对大家有所帮助。
0
0
复制全文