现在网站开发用什么环境,做网站优化选阿里巴巴还是百度,东莞网站建设哪里好,如何改进网站服务建设和管理文章目录 一#xff0c;面向对象概述二#xff0c;类和对象#xff08;一#xff09;类和对象的概述#xff08;二#xff09;定义类的补充注意事项 三#xff0c;封装四#xff0c;就近原则和this关键字#xff08;一#xff09;就近原则#xff08;二#xff09;… 文章目录 一面向对象概述二类和对象一类和对象的概述二定义类的补充注意事项 三封装四就近原则和this关键字一就近原则二this关键字 五构造方法一构造方法的概述二构造方法的作用二构造方法的种类及各自的作用三构造方法的注意事项 六标准的JavaBean类七三种情况的对象内存图一一个对象的内存图二多个对象的内存图三两个变量指向同一个对象的内存图 八基本数据类型和引用数据类型一基本数据类型二引用数据类型 九this的内存原理十成员变量和局部变量一成员变量二局部变量三成员变量和局部变量的区别 十一综合练习一文字版格斗游戏二对象数组练习1对象数组12对象数组23对象数组34定义数组45对象数组5 一面向对象概述
Java是一种面向对象的编程语言面向对象是一种编程范式它将程序设计看作是对象的集合每个对象都有自己的状态和行为并通过相互之间的消息传递来进行交互。
在面向对象的编程中可以通过定义类来创建对象。类是一种模板或者蓝图描述了对象的属性和行为。对象是类的实例化它具有类所定义的属性和行为。
面向对象的编程有以下几个核心概念 类Class类是对象的抽象描述了一类具有相同属性和行为的对象。它定义了对象的结构和行为。 对象Object对象是类的实例化是具体的实体具有类定义的属性和行为。 属性Attribute属性是对象的状态描述了对象的特征。 方法Method方法是对象的行为描述了对象可以做什么。 封装Encapsulation封装是将对象的属性和方法封装在一起隐藏内部实现细节只对外提供必要的接口。 继承Inheritance继承是一种机制允许创建一个新的类从已有的类派生出来。子类继承父类的属性和方法并可以添加自己特有的属性和方法。 多态Polymorphism多态是指同一个类的对象在不同的情况下表现出不同的行为。通过继承和方法重写实现了多态。
面向对象的编程具有封装性、继承性和多态性等特点可以提高代码的可重用性、可维护性和可扩展性。它使得程序的设计更加模块化更易于理解和修改。面向对象的编程在Java中得到了广泛应用并且是Java语言的基本特性之一。
二类和对象
一类和对象的概述
在Java中类是面向对象编程的基本单位它是对象的抽象描述定义了对象的属性和行为。而对象是类的实例化具体的实体拥有类所定义的属性和行为。
类的定义通常包括以下几个部分 类声明使用关键字class来声明一个类后面跟类的名称。 属性成员变量类的属性是描述对象特征的变量可以是基本数据类型或者其他类的对象。属性定义在类的内部可以通过访问修饰符来控制访问权限。 方法类的方法是描述对象行为的函数定义了对象可以做什么。方法也定义在类的内部可以通过访问修饰符来控制访问权限。 构造方法构造方法是一种特殊的方法用于创建对象时进行初始化操作。构造方法的名称与类的名称相同没有返回类型并且可以重载。 访问修饰符访问修饰符用于控制类、属性和方法的访问权限包括public、protected、private和默认不声明访问修饰符。 类的关系类与类之间可能存在继承关系、实现关系和关联关系这些关系可以通过关键字extends、implements和引用类型变量来表示。
对象是类的实例化通过使用new关键字来创建类的对象。创建对象后可以使用对象的引用变量来访问对象的属性和调用对象的方法。
例如下面是一个简单的Java类和对象的示例
// 定义一个类
class Person {// 属性String name;int age;// 构造方法public Person(String name, int age) {this.name name;this.age age;}// 方法public void sayHello() {System.out.println(Hello, my name is name , Im age years old.);}
}// 创建对象并使用
public class Main {public static void main(String[] args) {// 创建Person对象Person person new Person(John, 25);// 访问对象的属性System.out.println(person.name); // 输出JohnSystem.out.println(person.age); // 输出25// 调用对象的方法person.sayHello(); // 输出Hello, my name is John, Im 25 years old.}
}在上面的示例中我们定义了一个Person类它有两个属性name和age和一个方法sayHello。然后在主函数中我们创建了一个Person对象并通过对象的引用变量来访问对象的属性和调用对象的方法。
二定义类的补充注意事项
在Java中定义类时除了遵循标准的JavaBean规范外还有一些补充的注意事项
类名的命名规范类名应该采用驼峰命名法首字母大写例如Person。文件名的命名规范Java源文件的文件名应该与类名相同并以.java为扩展名例如Person.java。包的命名规范如果类位于一个包中包名应该全部小写并使用点.作为分隔符例如com.example。包名应该反映类的层次结构和所属项目的唯一性。访问修饰符的使用类可以使用四种不同的访问修饰符public、protected、default即不写任何修饰符和private。根据需要选择适当的访问修饰符以控制类的可见性和访问权限。继承和接口实现Java中的类可以继承其他类并实现一个或多个接口。继承和接口实现通过关键字extends和implements来实现。成员变量和局部变量的命名规范成员变量应该使用驼峰命名法首字母小写例如age。局部变量应该使用驼峰命名法或者简短的命名例如i。类的设计原则在定义类时可以考虑一些设计原则如单一职责原则、开放封闭原则、依赖倒置原则等以提高代码的可维护性、可扩展性和可重用性。
在编写Java代码时遵循这些注意事项可以使代码更加规范、易读和易于维护。同时也可以提高代码的可移植性并与其他开发人员的代码保持一致。
三封装
在Java中封装是一种面向对象编程的重要概念它将类的属性和方法封装在一起对外部使用者隐藏了类的内部实现细节只暴露必要的接口供外部访问。
封装的目的是为了保护类的内部数据不被直接访问和修改只能通过类提供的公开方法进行操作。这样可以防止外部代码对内部数据的错误修改和意外访问提高代码的安全性和可维护性。
在Java中通过访问修饰符来实现封装 private私有访问修饰符只能在当前类中访问外部类无法直接访问。 public公共访问修饰符可以在任何地方访问。 protected受保护的访问修饰符可以在当前类、同一包内的类和子类中访问。 默认不声明访问修饰符默认访问修饰符只能在当前包内访问。
通常情况下类的属性都应该声明为私有(private)访问修饰符然后通过公共(public)的setter和getter方法来访问和修改属性的值。这样可以在setter和getter方法中加入额外的逻辑操作实现对属性的控制和保护。
下面是一个示例代码
class Person {private String name;private int age;public String getName() {return name;}public void setName(String name) {// 可以在setter方法中添加逻辑判断if (name ! null !name.isEmpty()) {this.name name;}}public int getAge() {return age;}public void setAge(int age) {// 可以在setter方法中添加逻辑判断if (age 0 age 100) {this.age age;}}
}public class Main {public static void main(String[] args) {Person person new Person();person.setName(John);person.setAge(25);System.out.println(person.getName()); // 输出JohnSystem.out.println(person.getAge()); // 输出25}
}在上面的示例中Person类的属性name和age都被声明为私有(private)访问修饰符外部无法直接访问。通过公共(public)的setter和getter方法来访问和修改属性的值并在setter方法中加入了逻辑判断保证属性值的有效性。
这样做的好处是Person类的内部实现细节对外部是隐藏的外部只能通过公共接口来操作属性提高了代码的安全性和可维护性。同时如果需要对属性的访问和修改进行额外的处理只需要在setter和getter方法中添加相应的逻辑即可。
四就近原则和this关键字
一就近原则
在Java中就近原则Lexical Scoping是指在程序中变量的作用域是由它在代码中声明的位置决定的。当程序中存在同名的变量时就近原则规定在给定作用域内优先使用最近声明的变量。
例如考虑以下示例代码
public class Main {public static void main(String[] args) {int x 5;{int x 10;System.out.println(x); // 输出10}System.out.println(x); // 输出5}
}在上面的代码中有两个同名的变量x。第一个x是在main方法中声明的第二个x是在一个代码块内部声明的。根据就近原则当我们在代码块内部访问变量x时应该使用最近声明的变量即x 10。而当我们在代码块外部访问变量x时应该使用最近的作用域中声明的变量即x 5。
就近原则在Java中非常重要它确保变量的作用域是可控的并避免了命名冲突和变量混淆的问题。在编写代码时我们应该养成良好的命名习惯避免使用相同的变量名以免造成误解和错误。同时合理使用代码块和方法等可以控制变量的作用域遵循就近原则使代码更加清晰易懂。
二this关键字
在Java中this是一个关键字它代表当前对象的引用。this关键字可以在类的成员方法中使用用于引用当前对象的成员变量和成员方法。
使用this关键字可以解决以下两种常见的问题
解决命名冲突当成员变量与方法参数或局部变量同名时使用this关键字可以明确指定要引用的是成员变量还是方法参数或局部变量。例如
public class Person {private String name;public void setName(String name) {this.name name;}
}// 使用示例
Person person new Person();
person.setName(John);在上面的例子中setName方法的参数名是name而成员变量也是name。为了解决命名冲突我们使用this关键字来引用成员变量即this.name name。
在构造方法中调用其他构造方法在一个类中可以定义多个构造方法重载当我们在一个构造方法中调用其他构造方法时可以使用this关键字。例如
public class Person {private String name;private int age;public Person(String name) {this.name name;}public Person(String name, int age) {this(name); // 调用另一个构造方法this.age age;}
}// 使用示例
Person person new Person(John, 25);在上面的例子中第二个构造方法调用了第一个构造方法使用this(name)的方式传递name参数这样可以避免代码的重复。
总之this关键字在Java中用于引用当前对象的成员变量和成员方法并且可以在构造方法中调用其他构造方法。它的使用可以帮助解决命名冲突和代码重复的问题。
五构造方法
一构造方法的概述
构造方法Constructor是一种特殊的方法用于创建对象并初始化对象的属性。在Java中每个类都可以有一个或多个构造方法。
构造方法的概述如下
构造方法的名称必须与类名完全相同且没有返回类型包括void。构造方法可以有零个或多个参数用于接收外部传入的值。构造方法可以重载即一个类可以有多个构造方法只要它们的参数列表不同。如果类没有显式定义构造方法系统会自动提供一个默认的无参构造方法。但如果在类中定义了带参数的构造方法系统不会自动提供默认构造方法需要手动定义。构造方法可以有访问修饰符如public、protected、private或默认即没有修饰符。根据需要可以选择适当的访问修饰符来控制构造方法的访问权限。构造方法通常用于在创建对象时进行属性的初始化。在构造方法中可以使用传入的参数对对象的属性进行赋值。构造方法在使用new关键字创建对象时被调用创建对象并分配内存空间。构造方法会在对象创建完成后立即执行。构造方法不能通过对象来调用只能通过new关键字来调用。构造方法可以使用this关键字来调用同一个类中的其他构造方法称为构造方法链。通过构造方法链可以在创建对象时使用不同的构造方法来进行属性初始化。
构造方法的主要作用是初始化对象的属性并提供不同的方式来创建对象。合理地使用构造方法可以确保对象的属性被正确初始化并满足不同场景下的需求。
二构造方法的作用
Java构造方法是一种特殊的方法它的作用是用于创建对象并初始化对象的属性。它的名称必须与类名相同并且没有返回类型包括void。构造方法在使用new关键字时自动调用用于在内存中分配对象的空间并对对象的属性进行初始化。
构造方法的作用包括 创建对象构造方法用于在内存中创建对象的实例。当使用new关键字创建对象时系统会自动调用对应类的构造方法通过构造方法分配对象所需的内存空间。 初始化对象属性构造方法可以对对象的属性进行初始化为对象的属性赋予初始值。通过在构造方法中设置参数可以在创建对象时为属性传递初始值。 提供默认构造方法如果类没有显式定义构造方法系统会自动提供一个默认的无参构造方法。默认构造方法可以在创建对象时进行调用。如果类中有自定义的构造方法但没有提供无参构造方法那么在创建对象时如果没有传递参数编译器会报错。 初始化对象的状态构造方法可以在创建对象时对对象的状态进行初始化例如设置对象的初始状态、连接数据库等操作。 控制对象的创建过程通过构造方法的重载和访问修饰符的使用可以控制对象的创建过程限制对象的访问权限等。
总结来说构造方法在创建对象时起到了至关重要的作用它不仅用于分配对象的内存空间还可以对对象的属性进行初始化提供默认构造方法初始化对象的状态以及控制对象的创建过程。构造方法在类的定义中起到了重要的作用是面向对象编程中的一个基本概念。
二构造方法的种类及各自的作用
在Java中构造方法可以分为以下几种类型 默认构造方法无参构造方法如果类没有显式定义构造方法系统会自动提供一个默认的无参构造方法。默认构造方法没有任何参数并且什么都不做。它的作用是创建对象并分配内存空间但不对对象的属性进行初始化。 带参数的构造方法带参数的构造方法可以接受一个或多个参数用于在创建对象时传递初始值。通过在构造方法中设置参数可以对对象的属性进行初始化。带参数的构造方法可以根据不同的参数组合进行重载以满足不同的需求。 重载构造方法在一个类中可以定义多个构造方法只要它们的参数列表不同。重载构造方法的作用是提供多种创建对象的方式根据不同的参数组合来初始化对象的属性。 私有构造方法私有构造方法是指访问修饰符为private的构造方法它仅在本类中可见外部无法直接访问。私有构造方法的作用是限制对象的创建通常用于实现单例模式或工具类确保只能通过特定的方式创建对象。 构造方法链在一个构造方法中可以使用this关键字调用同一个类中的其他构造方法称为构造方法链。构造方法链的作用是在创建对象时可以通过不同的构造方法来进行属性初始化避免代码重复。
总结来说构造方法的种类包括默认构造方法、带参数的构造方法、重载构造方法、私有构造方法和构造方法链。它们的作用分别是创建对象并分配内存空间、对对象的属性进行初始化、提供多种创建对象的方式、限制对象的创建、以及在构造方法中调用其他构造方法来避免代码重复。不同的构造方法可以根据需求灵活地使用。
三构造方法的注意事项
在使用构造方法时需要注意以下几点 构造方法与类名相同构造方法的名称必须与类名完全相同并且没有返回类型包括void。如果构造方法的名称与类名不一致它会被当作普通方法而不是构造方法。 构造方法的重载一个类可以有多个构造方法只要它们的参数列表不同。构造方法的重载可以提供多种创建对象的方式根据不同的参数组合进行初始化。 默认构造方法的提供如果类没有显式定义构造方法系统会自动提供一个默认的无参构造方法。但是如果在类中定义了带参数的构造方法系统不会自动提供默认构造方法需要手动定义。 构造方法的访问修饰符构造方法可以使用public、protected、private或默认即没有修饰符这些访问修饰符。根据需要可以选择适当的访问修饰符来控制构造方法的访问权限。 构造方法的调用通过使用new关键字来调用构造方法创建对象并分配内存空间。构造方法可以在创建对象时进行属性的初始化但不能在创建对象后再次调用。 构造方法的链式调用在一个构造方法中可以使用this关键字调用同一个类中的其他构造方法称为构造方法链。通过构造方法链可以在创建对象时使用不同的构造方法来进行属性初始化。 私有构造方法的使用私有构造方法的访问权限仅限于类内部外部无法直接访问。私有构造方法通常用于实现单例模式或工具类限制对象的创建。 构造方法不能被继承构造方法不会被继承子类不能直接调用父类的构造方法。子类中可以使用super关键字来调用父类的构造方法用于初始化继承自父类的属性。
以上是在使用构造方法时需要注意的几点。合理地使用构造方法可以正确初始化对象的属性并控制对象的创建和访问权限。
六标准的JavaBean类
在Java中标准的JavaBean类是一种遵循特定规范的类用于封装数据并提供访问和操作这些数据的方法。JavaBean类通常用于在不同层之间传递数据例如在Web开发中存储和传递表单数据。
标准的JavaBean类应该满足以下要求
类必须具有一个公共的无参构造方法这允许使用默认的构造方法实例化JavaBean对象。属性必须是私有的JavaBean类通常将属性声明为私有并通过公共的getter和setter方法提供对属性的访问。提供公共的getter和setter方法JavaBean类应该为每个属性提供公共的getter和setter方法以允许其他类访问和修改属性的值。实现Serializable接口可选如果JavaBean类需要被序列化或者需要在网络上传输可以实现Serializable接口。
以下是一个示例的标准JavaBean类
public class Person implements Serializable {private String name;private int age;public Person() {// 默认的无参构造方法}public String getName() {return name;}public void setName(String name) {this.name name;}public int getAge() {return age;}public void setAge(int age) {this.age age;}
}在上面的示例中Person类是一个标准的JavaBean类。它满足了以下要求拥有一个公共的无参构造方法、私有的属性、公共的getter和setter方法并可选择实现Serializable接口。
标准的JavaBean类可以被用于各种用途例如在Spring框架中作为数据传输对象DTO在Hibernate中作为持久化实体类等。通过遵循JavaBean规范可以更好地封装和管理数据并提供对数据的访问和操作。
七三种情况的对象内存图
一一个对象的内存图
下面是一个Java对象的内存图示例
---------------------------
| |
| Object Header |
| |
---------------------------
| Instance Variables |
| |
---------------------------
| |
| Padding |
| |
---------------------------Java对象的内存图主要包括以下几个部分
Object Header对象头包含一些与对象相关的元数据如对象的哈希码、锁状态、GC标记等信息。Instance Variables实例变量存储对象的属性值。每个实例变量占用一定的内存空间。Padding内存对齐填充用于保持对象的对齐性和性能优化。
在内存中Java对象被分配在堆Heap中。当使用new关键字创建对象时会在堆中分配一块连续的内存空间来存储对象的实例变量。对象头和内存对齐填充不计入对象的实例变量空间。
实例变量可以是基本数据类型如int、double等或者引用类型如String、数组等。对于引用类型的实例变量实际存储的是对对象的引用而不是对象本身。
通过给对象的实例变量赋值可以修改对象的属性值。不同的对象拥有独立的内存空间因此它们的属性可以独立地进行修改和访问。
在Java中对对象的内存管理由垃圾回收器Garbage Collector负责。当对象不再被引用时垃圾回收器会自动回收对象所占用的内存空间以供后续的对象分配使用。
二多个对象的内存图
下面是一个Java程序中多个对象的内存图示例
------------------------------
| Object Header |
------------------------------
| Instance Variables |
------------------------------
| Padding |
------------------------------------------------------------
| Object Header |
------------------------------
| Instance Variables |
------------------------------
| Padding |
------------------------------...每个Java对象都有自己的内存图对象之间互相独立存储并且拥有相同的结构。每个对象的内存图都包含了对象头、实例变量和内存对齐填充。
在内存中每个对象都被分配在堆Heap中的不同的内存空间上。当创建多个对象时Java会在堆中分配多个连续的内存块来存储每个对象的实例变量。每个对象的实例变量可以独立地进行修改和访问。
不同对象的内存图之间可以有共享的实例变量即多个对象的同一实例变量指向同一个内存位置。这通常发生在引用类型的实例变量中当多个对象引用同一个对象时它们的实例变量指向同一个对象的引用。
Java中的垃圾回收器Garbage Collector会自动回收不再被引用的对象所占用的内存空间。当对象不再被引用时垃圾回收器会将其标记为垃圾并在适当的时候回收它们占用的内存以供后续的对象分配使用。
总结来说多个对象的内存图在堆中是独立分配的每个对象拥有自己的对象头、实例变量和内存对齐填充。对象之间可以共享引用类型的实例变量而垃圾回收器会负责回收不再被引用的对象。
三两个变量指向同一个对象的内存图
下面是一个Java程序中两个变量指向同一个对象的内存图示例
------------------------
| Variable 1 |
------------------------
| Memory Address |
------------------------|v------------------------
| Variable 2 |
------------------------
| Memory Address |
------------------------|v------------------------------
| Object Header |
------------------------------
| Instance Variables |
------------------------------
| Padding |
------------------------------在上面的示例中Variable 1和Variable 2是两个Java变量它们都存储了同一个对象的内存地址。这意味着两个变量实际上指向了同一个对象。
在堆中有一个对象被分配了内存空间它有一个对象头和实例变量。Variable 1和Variable 2存储了该对象在内存中的地址通过这个地址它们可以共享访问该对象的实例变量。
修改一个变量所指向的对象的状态将会影响到通过另一个变量访问的对象状态。这是因为两个变量指向的是同一个对象它们共享同一个对象的内存空间。
在Java中对象的引用是一个指向对象的内存地址的值而不是对象本身。这允许多个变量引用同一个对象从而实现对象之间的共享和相互影响。垃圾回收器会负责回收不再被引用的对象所占用的内存空间但只有当所有引用该对象的变量都不再引用它时对象才会被认为是不再被引用的垃圾。
八基本数据类型和引用数据类型
一基本数据类型
Java基本数据类型是指Java语言中的基本数据类型它们是预定义的不是由类定义的。Java的基本数据类型包括以下几种
byte表示8位有符号整数范围为-128到127。short表示16位有符号整数范围为-32,768到32,767。int表示32位有符号整数范围为-231到231-1。long表示64位有符号整数范围为-263到263-1。float表示32位单精度浮点数范围为正负3.40282347e38F有效位数为6-7位。double表示64位双精度浮点数范围为正负1.79769313486231570e308有效位数为15位。boolean表示布尔值只有两个取值true和false。char表示16位Unicode字符。
基本数据类型在内存中占用固定大小的空间它们被直接存储在栈中而不是在堆中与引用类型不同。每种基本数据类型都有对应的包装类用于提供与该数据类型相关的操作和方法。
基本数据类型的主要优点是效率高占用的内存空间较小。然而它们无法直接调用方法因为它们不是对象所以需要使用包装类来操作基本数据类型的一些特殊需求例如进行比较、转换等操作。
二引用数据类型
Java引用数据类型是指Java语言中的非基本数据类型也称为对象类型它们是由类或接口创建的。Java的引用数据类型包括以下几种
类Class引用数据类型最常见的形式就是类。类是一种自定义的数据类型它可以包含属性成员变量和方法成员方法并可以创建该类的对象。接口Interface接口是一种定义一组方法签名的引用数据类型它可以被类实现从而使类具有接口中定义的行为。数组Array数组是一种用来存储相同类型数据的容器可以存储基本数据类型或引用数据类型的元素。枚举Enum枚举是一种特殊的引用数据类型它限制变量只能取特定的值这些值在枚举类型中预先定义。字符串String字符串是一种引用数据类型它表示一串字符序列。在Java中字符串是不可变的即一旦创建就不能被修改。
引用数据类型的对象存储在堆内存中而引用变量本身存储在栈内存中。与基本数据类型不同引用数据类型的变量可以调用方法并且可以通过引用来操作对象的属性和行为。当对象没有被任何引用变量引用时它将成为垃圾并由Java的垃圾回收机制自动回收内存。
九this的内存原理
在Java中关键字this代表当前对象的引用。它可以在对象的方法中使用用来访问当前对象的成员变量和成员方法。
内存原理方面每当我们创建一个对象时Java会在堆内存中为该对象分配一块内存空间并将对象的成员变量存储在这个内存空间中。同时Java会为这个对象创建一个指向该内存空间的引用。
当我们在对象的方法中使用this关键字时编译器会将this关键字解析为对当前对象的引用。具体地说编译器会通过将this关键字作为方法参数传递给方法从而使方法能够访问当前对象的成员变量和成员方法。
在内存中每个线程都会有一个栈称为线程栈。当一个方法被调用时Java会在当前线程的栈中创建一个栈帧栈帧包含了方法的局部变量、方法参数以及方法返回值等信息。此时this关键字被存储在栈帧中的一个特殊位置用于指向当前对象的内存空间。
总结起来Java中的this关键字是一个指向当前对象的引用它在对象的方法中使用。它的内存原理是通过在当前线程的栈帧中存储一个指向当前对象的引用从而使方法能够访问当前对象的成员变量和成员方法。
十成员变量和局部变量
一成员变量
Java中的成员变量也称为实例变量是定义在类中的变量。它们是属于对象的每个对象都有自己的一份成员变量副本用来存储对象的状态和属性。
成员变量有以下特点
作用域成员变量的作用域是整个类可以在类的任何方法、构造方法、代码块中访问。生命周期成员变量的生命周期与对象的生命周期一致。当对象被创建时成员变量就分配相应的内存空间当对象被销毁时成员变量的内存空间也被释放。默认值如果没有显式赋值成员变量会有默认值。例如整型的成员变量默认值为0布尔型的成员变量默认值为false。访问性成员变量可以使用访问修饰符进行限制例如public、private、protected等。根据访问修饰符的不同成员变量可以被不同的类和方法访问。
成员变量通常用来存储对象的属性和状态信息可以在类的各个方法中使用和修改。它们在类中声明但在方法中不进行初始化赋值而是在对象创建时随着对象的初始化而赋予初始值。
二局部变量
Java中的局部变量是在方法、构造方法或代码块中声明的变量。它们只在声明的方法、构造方法或代码块中可见并且只在方法、构造方法或代码块的执行期间存在。
局部变量有以下特点
作用域局部变量的作用域限定在声明它的方法、构造方法或代码块中。超出该作用域局部变量将不再可见。生命周期局部变量的生命周期与方法、构造方法或代码块的执行周期一致。在方法、构造方法或代码块执行结束后局部变量的内存空间将被释放。必须显式初始化局部变量在使用前必须进行显式初始化。否则编译器会报错。不具有默认值与成员变量不同局部变量没有默认值。在使用前必须赋值。
局部变量通常用于临时存储和处理方法、构造方法或代码块中的数据。它们在方法、构造方法或代码块内部声明只在所声明的方法、构造方法或代码块中有效。一旦执行离开该方法、构造方法或代码块局部变量的内存空间会被释放。
三成员变量和局部变量的区别
Java中的成员变量和局部变量是两种不同类型的变量它们在作用域、生命周期和访问性等方面有所不同。 作用域 成员变量也称为实例变量是定义在类中、方法之外的变量。它的作用域是整个类可以被类中的所有方法访问。局部变量是定义在方法、构造方法、代码块中的变量。它的作用域只在声明的方法中只能在方法内部访问。 生命周期 成员变量的生命周期与对象的生命周期一致。当对象被创建时成员变量就分配相应的内存空间当对象被销毁时成员变量的内存空间也被释放。局部变量的生命周期在方法执行时开始在方法执行结束后结束。当方法执行完毕时局部变量的内存空间也会被释放。 初始化值 成员变量可以有默认值如果没有显式赋值它们会根据数据类型而有所不同。例如整型的成员变量默认值为0布尔型的成员变量默认值为false。局部变量没有默认值必须在使用之前显式赋值否则会编译错误。 访问性 成员变量可以使用访问修饰符进行限制例如public、private、protected等。根据访问修饰符的不同成员变量可以被不同的类和方法访问。局部变量没有访问修饰符它们只能在声明的方法内部访问。
总结起来成员变量是定义在类中和方法之外的变量作用域是整个类生命周期与对象一致而局部变量是定义在方法、构造方法和代码块中的变量作用域只在声明的方法内部生命周期在方法执行期间。
十一综合练习
一文字版格斗游戏
需求格斗游戏每个游戏角色的姓名血量都不相同在选定人物的时候new对象的时候这些信息就应该被确定下来。
下面是一个使用面向对象的Java代码示例实现带有姓名和血量的文字版格斗游戏
import java.util.Random;
import java.util.Scanner;public class FightGame {private static final int MAX_HEALTH 100;private static final int MAX_ATTACK_DAMAGE 20;public static void main(String[] args) {Scanner scanner new Scanner(System.in);Random random new Random();System.out.println(欢迎来到文字版格斗游戏);System.out.print(请输入你的角色名字);String playerName scanner.nextLine();System.out.print(请输入你的角色生命值1- MAX_HEALTH );int playerHealth scanner.nextInt();Player player new Player(playerName, playerHealth);Enemy enemy new Enemy(敌人, MAX_HEALTH);System.out.println(你的角色名字是 player.getName());System.out.println(你的初始生命值为 player.getHealth());System.out.println(敌人的生命值为 enemy.getHealth());System.out.println(游戏开始);while (player.getHealth() 0 enemy.getHealth() 0) {System.out.print(请输入你的攻击力1- MAX_ATTACK_DAMAGE );int playerAttack scanner.nextInt();int enemyAttack random.nextInt(MAX_ATTACK_DAMAGE) 1;enemy.takeDamage(playerAttack);player.takeDamage(enemyAttack);System.out.println(你对敌人造成了 playerAttack 点伤害);System.out.println(敌人对你造成了 enemyAttack 点伤害);System.out.println(你的剩余生命值为 player.getHealth());System.out.println(敌人的剩余生命值为 enemy.getHealth());}if (player.getHealth() 0) {System.out.println(你输了游戏);} else {System.out.println(你赢了游戏);}System.out.println(游戏结束);}
}class Character {private String name;private int health;public Character(String name, int health) {this.name name;this.health health;}public void takeDamage(int damage) {health - damage;if (health 0) {health 0;}}public String getName() {return name;}public int getHealth() {return health;}
}class Player extends Character {public Player(String name, int health) {super(name, health);}
}class Enemy extends Character {public Enemy(String name, int health) {super(name, health);}
}在这个示例中我们创建了一个Character类作为角色的基类其中包含了姓名和血量两个属性以及受伤的方法。Player类和Enemy类继承自Character类分别表示玩家和敌人角色。在实例化Player和Enemy对象时需要传入姓名和血量参数来初始化对象。
在主方法中我们首先根据玩家输入的姓名和血量创建了Player对象和Enemy对象。然后通过调用对象的方法来获取和修改角色的属性。游戏过程中玩家和敌人轮流攻击并根据攻击造成的伤害来更新角色的血量。最后根据玩家和敌人的血量判断游戏的胜负并输出相应的结果。
二对象数组练习
1对象数组1
需求定义数组存储3个商品对象。 商品的属性商品的id名字价格库存。 创建三个商品对象并把商品对象存入到数组当中。
下面是一个使用面向对象的Java代码示例实现创建商品对象并存储到对象数组中
import java.util.Scanner;public class ProductArray {public static void main(String[] args) {Scanner scanner new Scanner(System.in);Product[] products new Product[3];for (int i 0; i products.length; i) {System.out.println(请输入第 (i 1) 个商品的信息);System.out.print(商品ID);int id scanner.nextInt();System.out.print(商品名称);String name scanner.next();System.out.print(商品价格);double price scanner.nextDouble();System.out.print(商品库存);int stock scanner.nextInt();Product product new Product(id, name, price, stock);products[i] product;}System.out.println(三个商品的信息如下);for (int i 0; i products.length; i) {System.out.println(商品ID products[i].getId());System.out.println(商品名称 products[i].getName());System.out.println(商品价格 products[i].getPrice());System.out.println(商品库存 products[i].getStock());System.out.println(---------------------------);}}
}class Product {private int id;private String name;private double price;private int stock;public Product(int id, String name, double price, int stock) {this.id id;this.name name;this.price price;this.stock stock;}public int getId() {return id;}public String getName() {return name;}public double getPrice() {return price;}public int getStock() {return stock;}
}在这个示例中我们创建了一个Product类来表示商品包含了商品的ID、名称、价格和库存四个属性。在ProductArray类的主方法中我们首先定义了一个长度为3的Product数组用于存储商品对象。
然后通过循环从用户输入中获取每个商品的信息并使用构造方法创建Product对象。将每个创建的Product对象存储到数组中。
最后通过遍历数组将每个商品对象的属性打印出来展示给用户。
2对象数组2
需求定义数组存储3部汽车对象。 汽车的属性品牌价格颜色。 创建三个汽车对象数据通过键盘录入而来并把数据存入到数组当中。
下面是一个使用面向对象的Java代码示例实现创建汽车对象并存储到对象数组中
import java.util.Scanner;public class CarArray {public static void main(String[] args) {Scanner scanner new Scanner(System.in);Car[] cars new Car[3];for (int i 0; i cars.length; i) {System.out.println(请输入第 (i 1) 部汽车的信息);System.out.print(汽车品牌);String brand scanner.next();System.out.print(汽车价格);double price scanner.nextDouble();System.out.print(汽车颜色);String color scanner.next();Car car new Car(brand, price, color);cars[i] car;}System.out.println(三部汽车的信息如下);for (int i 0; i cars.length; i) {System.out.println(汽车品牌 cars[i].getBrand());System.out.println(汽车价格 cars[i].getPrice());System.out.println(汽车颜色 cars[i].getColor());System.out.println(---------------------------);}}
}class Car {private String brand;private double price;private String color;public Car(String brand, double price, String color) {this.brand brand;this.price price;this.color color;}public String getBrand() {return brand;}public double getPrice() {return price;}public String getColor() {return color;}
}在这个示例中我们创建了一个Car类来表示汽车包含了汽车的品牌、价格和颜色三个属性。在CarArray类的主方法中我们首先定义了一个长度为3的Car数组用于存储汽车对象。
然后通过循环从用户输入中获取每辆汽车的信息并使用构造方法创建Car对象。将每个创建的Car对象存储到数组中。
最后通过遍历数组将每辆汽车对象的属性打印出来展示给用户。
3对象数组3
需求定义数组存储3部手机对象。 手机的属性品牌价格颜色。 要求计算出三部手机的平均价格。
下面是一个使用面向对象的Java代码示例实现创建手机对象并计算平均价格
import java.util.Scanner;public class PhoneArray {public static void main(String[] args) {Scanner scanner new Scanner(System.in);Phone[] phones new Phone[3];for (int i 0; i phones.length; i) {System.out.println(请输入第 (i 1) 部手机的信息);System.out.print(手机品牌);String brand scanner.next();System.out.print(手机价格);double price scanner.nextDouble();System.out.print(手机颜色);String color scanner.next();Phone phone new Phone(brand, price, color);phones[i] phone;}double total 0;for (int i 0; i phones.length; i) {total phones[i].getPrice();}double average total / phones.length;System.out.println(三部手机的平均价格为 average);}
}class Phone {private String brand;private double price;private String color;public Phone(String brand, double price, String color) {this.brand brand;this.price price;this.color color;}public String getBrand() {return brand;}public double getPrice() {return price;}public String getColor() {return color;}
}在这个示例中我们创建了一个Phone类来表示手机包含了手机的品牌、价格和颜色三个属性。在PhoneArray类的主方法中我们首先定义了一个长度为3的Phone数组用于存储手机对象。
然后通过循环从用户输入中获取每部手机的信息并使用构造方法创建Phone对象。将每个创建的Phone对象存储到数组中。
接着我们使用一个变量total来累加所有手机的价格。然后通过除以数组的长度来计算平均价格。
最后我们将计算出的平均价格打印出来展示给用户。
4定义数组4
需求定义数组存储4个女朋友对象。 女朋友的属性姓名年龄性别爱好。 要求1计算出四个女朋友的平均年龄。 要求2统计年龄比平均值低的女朋友有几个并把她们的所有信息打印出来。
下面是一个使用面向对象的Java代码示例实现创建女朋友对象并计算平均年龄以及统计年龄低于平均值的女朋友数量并打印她们的信息
import java.util.Scanner;public class GirlfriendArray {public static void main(String[] args) {Scanner scanner new Scanner(System.in);Girlfriend[] girlfriends new Girlfriend[4];for (int i 0; i girlfriends.length; i) {System.out.println(请输入第 (i 1) 个女朋友的信息);System.out.print(姓名);String name scanner.next();System.out.print(年龄);int age scanner.nextInt();System.out.print(性别);String gender scanner.next();System.out.print(爱好);String hobby scanner.next();Girlfriend girlfriend new Girlfriend(name, age, gender, hobby);girlfriends[i] girlfriend;}int totalAge 0;for (int i 0; i girlfriends.length; i) {totalAge girlfriends[i].getAge();}int averageAge totalAge / girlfriends.length;System.out.println(四个女朋友的平均年龄为 averageAge);int count 0;System.out.println(年龄低于平均值的女朋友有);for (int i 0; i girlfriends.length; i) {if (girlfriends[i].getAge() averageAge) {count;System.out.println(girlfriends[i].toString());}}System.out.println(共有 count 个女朋友的年龄低于平均值。);}
}class Girlfriend {private String name;private int age;private String gender;private String hobby;public Girlfriend(String name, int age, String gender, String hobby) {this.name name;this.age age;this.gender gender;this.hobby hobby;}public String getName() {return name;}public int getAge() {return age;}public String getGender() {return gender;}public String getHobby() {return hobby;}Overridepublic String toString() {return 姓名 name 年龄 age 性别 gender 爱好 hobby;}
}在这个示例中我们创建了一个Girlfriend类来表示女朋友包含了女朋友的姓名、年龄、性别和爱好四个属性。在GirlfriendArray类的主方法中我们首先定义了一个长度为4的Girlfriend数组用于存储女朋友对象。
然后通过循环从用户输入中获取每个女朋友的信息并使用构造方法创建Girlfriend对象。将每个创建的Girlfriend对象存储到数组中。
接着我们使用一个变量totalAge来累加所有女朋友的年龄。然后通过除以数组的长度来计算平均年龄。
最后我们遍历数组判断每个女朋友的年龄是否低于平均值如果是则将其打印出来并统计数量。
同时我们在Girlfriend类中重写了toString方法用于返回女朋友对象的信息。
5对象数组5
需求定义一个长度为3的数组数组存储1~3名学生对象作为初始化数据学生对象的学号姓名各不相同。 学生的属性学号姓名年龄。 要求1再次添加一个学生对象并在添加的时候进行学号的唯一判断。 要求2添加完毕之后遍历所有学生信息。 要求3通过id删除学生信息如果存在则删除如果不存在则表示删除失败。 要求4删除完毕之后遍历所有学生信息。 要求5查询数组id为 “2023002” 的学生如果存在则将他的年龄1岁。
下面是一个使用面向对象的Java代码示例实现创建学生对象数组并实现添加、删除、遍历和查询学生信息的功能
import java.util.Scanner;public class StudentArray {public static void main(String[] args) {Scanner scanner new Scanner(System.in);Student[] students new Student[3];students[0] new Student(2023001, 张三, 18);students[1] new Student(2023002, 李四, 19);students[2] new Student(2023003, 王五, 20);System.out.println(当前学生信息如下);printStudents(students);System.out.println(请输入要添加的学生信息);System.out.print(学号);String id scanner.next();System.out.print(姓名);String name scanner.next();System.out.print(年龄);int age scanner.nextInt();boolean isExist false;for (int i 0; i students.length; i) {if (students[i].getId().equals(id)) {isExist true;break;}}if (isExist) {System.out.println(学号已存在添加失败);} else {Student newStudent new Student(id, name, age);Student[] newStudents new Student[students.length 1];for (int i 0; i students.length; i) {newStudents[i] students[i];}newStudents[newStudents.length - 1] newStudent;students newStudents;System.out.println(添加成功);System.out.println(当前学生信息如下);printStudents(students);}System.out.print(请输入要删除的学生学号);String deleteId scanner.next();boolean isDeleted false;for (int i 0; i students.length; i) {if (students[i].getId().equals(deleteId)) {students[i] null;isDeleted true;break;}}if (isDeleted) {Student[] newStudents new Student[students.length - 1];int newIndex 0;for (int i 0; i students.length; i) {if (students[i] ! null) {newStudents[newIndex] students[i];newIndex;}}students newStudents;System.out.println(删除成功);System.out.println(当前学生信息如下);printStudents(students);} else {System.out.println(学号不存在删除失败);}System.out.print(请输入要查询的学生学号);String queryId scanner.next();boolean isFound false;for (int i 0; i students.length; i) {if (students[i].getId().equals(queryId)) {students[i].setAge(students[i].getAge() 1);isFound true;break;}}if (isFound) {System.out.println(年龄已加1岁);System.out.println(当前学生信息如下);printStudents(students);} else {System.out.println(学号不存在);}}public static void printStudents(Student[] students) {for (int i 0; i students.length; i) {System.out.println(students[i].toString());}}
}class Student {private String id;private String name;private int age;public Student(String id, String name, int age) {this.id id;this.name name;this.age age;}public String getId() {return id;}public String getName() {return name;}public int getAge() {return age;}public void setAge(int age) {this.age age;}Overridepublic String toString() {return 学号 id 姓名 name 年龄 age;}
}在这个示例中我们创建了一个Student类来表示学生包含了学生的学号、姓名和年龄三个属性。在StudentArray类的主方法中我们首先定义了一个长度为3的Student数组并初始化了数组的前3个元素。
然后我们通过输入获取要添加的学生信息并进行学号的唯一判断。如果学号已存在则添加失败否则创建一个新的Student对象并将其添加到新的数组中。
接着我们获取要删除的学生学号并进行判断。如果学号存在则将对应的数组元素置为null并创建一个新的数组来存储非null的元素从而实现删除。
然后我们获取要查询的学生学号并进行判断。如果学号存在则将对应的学生对象的年龄加1岁。
最后我们通过调用printStudents方法来遍历并打印所有学生信息。
同时我们在Student类中重写了toString方法用于返回学生对象的信息。