活动介绍

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面向对象编程基础的详细介绍,希望对大家有所帮助。
corwn 最低0.47元/天 解锁专栏
赠100次下载
点击查看下一篇
profit 400次 会员资源下载次数
profit 300万+ 优质博客文章
profit 1000万+ 优质下载资源
profit 1000万+ 优质文库回答
复制全文

李_涛

知名公司架构师
拥有多年在大型科技公司的工作经验,曾在多个大厂担任技术主管和架构师一职。擅长设计和开发高效稳定的后端系统,熟练掌握多种后端开发语言和框架,包括Java、Python、Spring、Django等。精通关系型数据库和NoSQL数据库的设计和优化,能够有效地处理海量数据和复杂查询。
最低0.47元/天 解锁专栏
赠100次下载
百万级 高质量VIP文章无限畅学
千万级 优质资源任意下载
千万级 优质文库回答免费看

最新推荐

编程中的数组应用与实践

### 编程中的数组应用与实践 在编程领域,数组是一种非常重要的数据结构,它可以帮助我们高效地存储和处理大量数据。本文将通过几个具体的示例,详细介绍数组在编程中的应用,包括图形绘制、随机数填充以及用户输入处理等方面。 #### 1. 绘制数组图形 首先,我们来创建一个程序,用于绘制存储在 `temperatures` 数组中的值的图形。具体操作步骤如下: 1. **创建新程序**:选择 `File > New` 开始一个新程序,并将其保存为 `GraphTemps`。 2. **定义数组和画布大小**:定义一个 `temperatures` 数组,并设置画布大小为 250 像素×250 像

并发编程:多语言实践与策略选择

### 并发编程:多语言实践与策略选择 #### 1. 文件大小计算的并发实现 在并发计算文件大小的场景中,我们可以采用数据流式方法。具体操作如下: - 创建两个 `DataFlowQueue` 实例,一个用于记录活跃的文件访问,另一个用于接收文件和子目录的大小。 - 创建一个 `DefaultPGroup` 来在线程池中运行任务。 ```plaintext graph LR A[创建 DataFlowQueue 实例] --> B[创建 DefaultPGroup] B --> C[执行 findSize 方法] C --> D[执行 findTotalFileS

设计与实现RESTfulAPI全解析

### 设计与实现 RESTful API 全解析 #### 1. RESTful API 设计基础 ##### 1.1 资源名称使用复数 资源名称应使用复数形式,因为它们代表数据集合。例如,“users” 代表用户集合,“posts” 代表帖子集合。通常情况下,复数名词表示服务中的一个集合,而 ID 则指向该集合中的一个实例。只有在整个应用程序中该数据类型只有一个实例时,使用单数名词才是合理的,但这种情况非常少见。 ##### 1.2 HTTP 方法 在超文本传输协议 1.1 中定义了八种 HTTP 方法,但在设计 RESTful API 时,通常只使用四种:GET、POST、PUT 和

AWSLambda冷启动问题全解析

### AWS Lambda 冷启动问题全解析 #### 1. 冷启动概述 在 AWS Lambda 中,冷启动是指函数实例首次创建时所经历的一系列初始化步骤。一旦函数实例创建完成,在其生命周期内不会再次经历冷启动。如果在代码中添加构造函数或静态初始化器,它们仅会在函数冷启动时被调用。可以在处理程序类的构造函数中添加显式日志,以便在函数日志中查看冷启动的发生情况。此外,还可以使用 X-Ray 和一些第三方 Lambda 监控工具来识别冷启动。 #### 2. 冷启动的影响 冷启动通常会导致事件处理出现延迟峰值,这也是人们关注冷启动的主要原因。一般情况下,小型 Lambda 函数的端到端延迟

Clojure多方法:定义、应用与使用场景

### Clojure 多方法:定义、应用与使用场景 #### 1. 定义多方法 在 Clojure 中,定义多方法可以使用 `defmulti` 函数,其基本语法如下: ```clojure (defmulti name dispatch-fn) ``` 其中,`name` 是新多方法的名称,Clojure 会将 `dispatch-fn` 应用于方法参数,以选择多方法的特定实现。 以 `my-print` 为例,它接受一个参数,即要打印的内容,我们希望根据该参数的类型选择特定的实现。因此,`dispatch-fn` 需要是一个接受一个参数并返回该参数类型的函数。Clojure 内置的

【Nokia 5G核心网运维自动化】:提升效率与降低错误率的6大策略

![5g核心网和关键技术和功能介绍-nokia.rar](https://www.viavisolutions.com/sites/default/files/images/diagram-sba.png) # 摘要 随着5G技术的快速发展,其核心网运维面临一系列新的挑战。本文首先概述了5G核心网运维自动化的必要性,然后详细分析了Nokia 5G核心网架构及其运维挑战,包括组件功能、架构演变以及传统运维的局限性。接着,文章探讨了自动化策略的基础理论与技术,包括自动化工具的选择和策略驱动的自动化设计。重点介绍了Nokia 5G核心网运维自动化策略实践,涵盖网络部署、故障诊断与性能优化的自动化实

机械臂三维建模的创新方法与趋势:引领潮流,掌握未来技术

![机械臂三维建模的创新方法与趋势:引领潮流,掌握未来技术](https://i2.hdslb.com/bfs/archive/1f955f5a45825d8aced9fb57300988afd885aebc.jpg@960w_540h_1c.webp) # 摘要 本文综合探讨了机械臂三维建模的理论基础、技术应用及未来发展趋势。首先介绍了机械臂三维建模的基本概念,随后详细阐述了三维空间坐标系统、几何建模和物理建模的基础理论。在此基础上,本文深入分析了利用CAD软件和参数化、模块化设计进行建模的方法,并探讨了高级建模技术。通过实际案例分析了三维建模技术在结构设计、仿真分析以及制造测试中的应用,

ApacheThrift在脚本语言中的应用

### Apache Thrift在脚本语言中的应用 #### 1. Apache Thrift与PHP 在使用Apache Thrift和PHP时,首先要构建I/O栈。以下是构建I/O栈并调用服务的基本步骤: 1. 将传输缓冲区包装在二进制协议中,然后传递给服务客户端的构造函数。 2. 构建好I/O栈后,打开套接字连接,调用服务,最后关闭连接。 示例代码中的异常捕获块仅捕获Apache Thrift异常,并将其显示在Web服务器的错误日志中。 PHP错误通常在Web服务器的上下文中在服务器端表现出来。调试PHP程序的基本方法是检查Web服务器的错误日志。在Ubuntu 16.04系统中

响应式Spring开发:从错误处理到路由配置

### 响应式Spring开发:从错误处理到路由配置 #### 1. Reactor错误处理方法 在响应式编程中,错误处理是至关重要的。Project Reactor为其响应式类型(Mono<T> 和 Flux<T>)提供了六种错误处理方法,下面为你详细介绍: | 方法 | 描述 | 版本 | | --- | --- | --- | | onErrorReturn(..) | 声明一个默认值,当处理器中抛出异常时发出该值,不影响数据流,异常元素用默认值代替,后续元素正常处理。 | 1. 接收要返回的值作为参数<br>2. 接收要返回的值和应返回默认值的异常类型作为参数<br>3. 接收要返回

在线票务系统解析:功能、流程与架构

### 在线票务系统解析:功能、流程与架构 在当今数字化时代,在线票务系统为观众提供了便捷的购票途径。本文将详细解析一个在线票务系统的各项特性,包括系统假设、范围限制、交付计划、用户界面等方面的内容。 #### 系统假设与范围限制 - **系统假设** - **Cookie 接受情况**:互联网用户不强制接受 Cookie,但预计大多数用户会接受。 - **座位类型与价格**:每场演出的座位分为一种或多种类型,如高级预留座。座位类型划分与演出相关,而非个别场次。同一演出同一类型的座位价格相同,但不同场次的价格结构可能不同,例如日场可能比晚场便宜以吸引家庭观众。 -