一、数组
在Java编程语言中,数组是一个可以存储固定大小的相同类型元素的数据结构。数组在内存中占据连续的空间,并且每个元素都可以通过其索引来访问。数组一旦创建,其大小就不能改变。
数组的声明和初始化
在Java中,声明一个数组时,你需要指定数组的类型和数组的名称。初始化数组时,你可以指定数组的大小,并为其分配内存空间。
// 声明一个整数数组
int[] myArray;
// 初始化数组
myArray = new int[5]; // 创建一个可以存储5个整数的数组
// 也可以在声明的同时初始化数组
int[] anotherArray = new int[10];
你还可以在声明和初始化数组的同时为数组元素赋值:
// 声明、初始化并赋值
int[] numbers = {1, 2, 3, 4, 5};
数组的访问和修改
你可以通过数组的索引来访问和修改数组中的元素。数组的索引从0开始,一直到数组长度减1。
// 访问数组中的元素
int firstElement = myArray[0];
int thirdElement = myArray[2];
// 修改数组中的元素
myArray[0] = 100;
myArray[2] = 200;
数组的长度
你可以使用数组的length
属性来获取数组的长度(即数组中元素的个数)。
int length = myArray.length;
多维数组
Java还支持多维数组,即数组的数组。最常见的是二维数组。
// 声明并初始化一个二维数组
int[][] matrix = {
{1, 2, 3},
{4, 5, 6},
{7, 8, 9}
};
// 访问二维数组中的元素
int element = matrix[1][2]; // 获取第二行第三列的元素,值为6
数组的遍历
你可以使用for循环来遍历数组中的所有元素:
for (int i = 0; i < myArray.length; i++) {
System.out.println(myArray[i]);
}
或者使用增强的for循环(foreach循环):
for (int element : myArray) {
System.out.println(element);
}
这些是Java数组的基础知识。数组是Java编程中非常常用和重要的数据结构之一。
二 、面向对象
面向对象(Object-Oriented,简称OO)是一种程序设计思想,它基于对象的概念,以对象为中心,类和继承为构造机制,来认识、理解、刻画客观世界和设计、构建相应的软件系统。面向对象的基本特征包括封装、继承和多态。
-
封装(Encapsulation):封装是指将数据(属性)和操作数据的方法(函数)结合在一起,形成“对象”。对象的状态信息隐藏在对象内部,不允许外部程序直接访问对象内部信息,而是通过该类提供的方法进行操作。封装的主要目的是增加安全性和简化编程,用户只需要知道对象提供哪些方法,而不需要了解内部的细节。
-
继承(Inheritance):继承是从已有的类派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。继承是代码复用的一种重要手段,它允许程序员在保持原有类特性的基础上进行修改和扩展,以得到广泛应用的类。
-
多态(Polymorphism):多态是指允许不同类的对象对同一消息做出响应。多态包括参数化多态和包含多态。多态性语言具有灵活、抽象、行为共享、代码共享等优势,很好地解决了应用程序函数同名问题。
除了上述三个基本特征外,面向对象编程还常常涉及到其他一些概念,如:
-
类(Class):类是对对象的抽象,是创建对象的蓝图或模板。它定义了对象所具有的属性和方法。
-
对象(Object):对象是类的实例,是一个具体的实体,它包含了类的属性和方法的具体值。
-
接口(Interface):接口定义了一个类必须遵循的规范,它描述了类应该具有的方法,但不提供具体的实现。接口可以被类实现(Implement),一个类可以实现多个接口。
-
抽象类(Abstract Class):抽象类是一种不能被实例化的类,它只能被继承。抽象类可以包含抽象方法和非抽象方法。
-
消息传递(Message Passing):对象之间通过发送消息来请求服务或传递信息。消息传递是对象之间进行交互的一种方式。
-
封装性、透明性、复用性:封装性隐藏了对象内部的复杂性;透明性指对象提供清晰的接口,使得使用者无需了解对象内部的实现细节;复用性指对象可以被多次使用,提高了代码的利用率。
面向对象编程可以提高软件的可维护性、可扩展性和可重用性,使得代码更加模块化、结构化和清晰易懂。
三、构造方法和方法重载
构造方法和方法重载是面向对象编程中的两个重要概念,它们分别有着不同的特点和作用。
构造方法是一个特殊类型的方法,它在对象被创建时自动调用,用于初始化对象的状态。构造方法的名称与类名相同,且没有返回类型。在Java等面向对象编程语言中,构造方法的主要任务是完成对象的初始化工作,如为对象的属性赋初值等。构造方法可以带有参数,以便为不同的对象提供不同的初值。
public class Person {
String name;
int age;
public Person() {
}//无参构造
public Person(String name, int age) {
this.name = name;
this.age = age;
}//有参构造
}
方法重载则是指在同一个类中定义多个方法,它们具有相同的名称但参数列表不同(参数类型、参数个数或参数顺序不同)。方法重载使得程序可以根据提供的参数类型和数量来选择合适的方法执行,从而提高了代码的灵活性和可读性。在面向对象编程中,方法重载通常用于实现具有相似功能但参数不同的方法。
// 无参数的方法
public void display() {
System.out.println("无参数的display方法被调用");
}
// 带有一个整数参数的方法
public void display(int number) {
System.out.println("带有一个整数参数的display方法被调用,数字是:" + number);
}
// 带有两个整数参数的方法
public void display(int number1, int number2) {
System.out.println("带有两个整数参数的display方法被调用,数字是:" + number1 + " 和 " + number2);
}
需要注意的是,构造方法虽然也可以进行重载(即定义多个构造方法,参数列表不同),但它们的名称必须与类名相同,且不能定义返回类型。而普通方法的重载则只需要满足方法名相同、参数列表不同的条件即可。
总的来说,构造方法和方法重载都是面向对象编程中的重要概念,它们分别用于对象的初始化和提高代码的灵活性和可读性。在实际编程中,合理地使用构造方法和方法重载可以使程序更加清晰、易于维护和扩展。
四、封装
在Java中,封装(Encapsulation)是面向对象编程的四大基本特征之一(其他三个是继承、多态和抽象)。封装是指将对象的状态信息(属性)和行为(方法)包装在一个单元(类)中,并且隐藏对象的内部实现细节,只对外提供必要的接口来访问对象的状态和行为。
封装的主要目的是:
- 数据隐藏:保护对象的状态信息不被外部直接访问和修改,只能通过对象提供的方法来进行操作。
- 提高安全性:防止外部代码随意修改对象的内部数据,从而导致对象的状态不一致或程序出错。
- 增加代码的可维护性:封装使得对象的内部实现可以自由修改,而不会影响使用对象的外部代码。
- 简化编程:外部代码只需要知道如何与对象交互,而不需要了解对象内部的复杂实现。
在Java中,实现封装的主要手段有:
-
使用访问修饰符:Java提供了public、protected、private等访问修饰符来控制类成员的访问权限。通常,我们将类的属性设置为private,然后通过public的方法来提供对属性的访问和修改。
-
使用getter和setter方法:对于私有属性,我们可以通过提供公共的getter(取值)和setter(设值)方法来允许外部代码间接地访问和修改这些属性。
下面是一个简单的Java封装示例:
public class Person {
// 私有属性,外部无法直接访问
private String name;
private int age;
// 公共的getter方法,用于获取属性值
public String getName() {
return name;
}
public int getAge() {
return age;
}
// 公共的setter方法,用于设置属性值
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
if (age >= 0) {
this.age = age;
} else {
System.out.println("Age cannot be negative.");
}
}
// 其他方法...
}
在这个例子中,Person
类封装了 name
和 age
两个私有属性,并且提供了公共的getter和setter方法来访问和修改这些属性。注意,在 setAge
方法中,我们还加入了对年龄值的合法性检查,这是封装带来的好处之一,即可以在设置属性值时加入额外的逻辑。
使用封装的好处是,我们可以随时改变Person
类的内部实现,比如增加属性的验证逻辑,而不会影响到使用Person
类的外部代码。只要外部代码仍然通过Person
类提供的公共接口来与Person
对象交互,那么内部实现的改变就不会影响到外部代码的功能。