一、前言:
在Java中,面向对象编程(Object-Oriented Programming, OOP)是一种核心的编程范式。Java的设计和开发都是基于面向对象的思想。面向对象编程的主要目的是提高代码的可重用性、灵活性和可维护性。以下是Java面向对象编程的一些关键概念和特点:
面向对象编程的基本特性:
封装 (Encapsulation):封装是将数据和对数据的操作绑定在一起的过程,并对外部隐藏内部实现细节。在Java中,通过使用访问控制符(如private, protected, public)以及构造器、getter和setter方法来实现封装。
继承 (Inheritance):继承允许创建一个新类(子类)继承现有类(父类)的属性和方法。这有助于减少代码重复并建立类之间的层次结构。
多态 (Polymorphism):多态是指一个接口可以有多种不同的实现方式。在Java中,可以通过方法重载(overloading)和方法覆盖(overriding)来实现多态。
抽象 (Abstraction):抽象是通过抽象类和接口来实现的,它允许定义行为而不关心具体的实现细节。
二、类
1、类是java中重要的数据类型(引用数据类型),是组成java程序的基本要素。它封装了一类对象数据和操作。
package 复杂数组对象练习;
public class Student {
private String name;
private int age;
private int id;
public Student() {
}
public Student(String name, int age, int id) {
this.name = name;
this.age = age;
this.id = id;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setId(int id) {
this.id = id;
}
}
以上是一个Student类的定义 ,在进行实例化的时候有两种方式:1、空参构造public Student() {}+set方法,这个需要我们在另一个文件中对每一个属性进行stu.setName("zhangsan"),等初始化操作,比较麻烦。2、全参构造public Student(String name, int age, int id) {
this.name = name;
this.age = age;
this.id = id;}这个需要我们在另一个测试文件中,在Student stu =new Student("zhangsan",19,001)时传递参数。
不过这个2种方式在以后都会使用到。例如,如果我现在需要把张三的id修改成002,那我们就不用在重新写变全参构造里面的参数,而是直接写,stu.setId("002")这一步就相当于修改了id。
三、面向对象综合练习
首先,我们在每一个文件中只定义类,public 。继续引用·上面的Student类
package 复杂数组对象练习;
public class Student {
private String name;
private int age;
private int id;
public Student() {
}
public Student(String name, int age, int id) {
this.name = name;
this.age = age;
this.id = id;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
public int getId() {
return id;
}
public void setName(String name) {
this.name = name;
}
public void setAge(int age) {
this.age = age;
}
public void setId(int id) {
this.id = id;
}
}
到此,我们Student类就定义完成了。不过如果,你使用的是idea的话,这一步可以有快捷键alt+insert,可以一键生成。
(2)、开始编写Student_Test测试类
package 复杂数组对象练习;
public class Student_Test {
public static void main(String[] args){
Student stu1=new Student("zhangsan",18,1);
Student stu2=new Student("lisi",19,2);
Student stu3=new Student("wangwu",20,3);}
这一步先完成三个学生初始化。然后我们在把这个三个学生的信息存在数组中,不过这里需要注意数组的数据类型是引用数据类型Student
Student [] arr={stu1,stu2,stu3};
这样我们就把对象存在数组中,此时arr数组是对象数组。
接下来,我们继续分析要求1:添加一个学生,对其学号做判断,那如果id不存在那就添加这名学生的信息,如果id重复就提升,重新修改学的id,那对于添加学生的信息而言,又有判断,这个数组是不是已经满了,如果满了,那就扩大数组,如果没满那就正常添加。
假设,我们现在的数组是这样的(上面的那个数组不算)。显然,这里的数组已经满了,而我们知道,数组是不可变数据类型,所以我们只能重新建一个数组来存储第四位同学的信息。
Student [] arr=new Student[3];
arr[0]=stu1;
arr[1]=stu2;
arr[2]=stu3;
这个时候我们可以在写一个方法在main方法的下面;
public static Student[] new_arr(Student[]arr){
//创建一个新的数组
Student [] new_arr=new Student [arr.length+1];
for(int i=0;i<arr.length;i++){
new_arr[i]=arr[i];
}
return new_arr;
}
很明显,这块实现了把老数组扩大1,生成一个新的数组来存下stu4对象的信息。
接下来,我需要对学号进行一致性判断,如果存在相等的id那简单直接打印重新修改id即可。如果不一样那就直接添加。
public static blooean contains(Student[]arr,int id){
for(int i=0;i<arr.length;i++){
//把arr数组中所有的对象通过循环来放到stu中
Student stu =arr[i];
//保证stu不会是空的
if(stu!=null){
int sid=stu.getId();
if(sid=stu.getId()){
return true;}
}
}return false;
}
然后,我们需要判断数组是不是已经满了,需要我们写一个方法来判断
public static int get_count(Student[]arr){
int count=0;
for(int i=0;i<arr.length;i++){
Student stu =arr[i];
if(stu!=null){
count++;
}
}
return count;
}
最后,我们需要打印一下信息:这块再写一个方法来完成
public static void print_arr(Student[] arr){
for (int i = 0; i < arr.length; i++) {
Student stu=arr[i];
if ( stu!=null ){
System.out.println(arr[i].getId()+" "+arr[i].getName()+" "+arr[i].getAge());
}
}
}
完成版(要求1和2):
package 复杂数组对象练习;
public class Student_Test {
public static void main(String[] args){
Student [] arr=new Student[3];
Student stu1=new Student("zhangsan",18,1);
Student stu2=new Student("lisi",19,2);
Student stu3=new Student("wangwu",20,3);
//把元素赋值给数组
arr[0]=stu1;
arr[1]=stu2;
arr[2]=stu3;
//1.再次添加一个学生,并在添加的时候做一个学号判断
Student stu4=new Student("zhaoliu",21,4);
//唯一性判断
//已经存在,那就不添加
//如果不存在,那就添加
boolean flag=contains(arr,stu4.getId());
if (flag){
System.out.println("已经存在了");
}
else {
int count=get_count(arr);
if ( count==arr.length ){
//扩充数组,在老的数组上+1
Student[] new_arr=create_arr(arr);
new_arr[count]=stu4;
print_arr(new_arr);
}
else {
//没有存满,直接加,由于拿到的count是数组中已经有的元素,所以可以不用在重新获取索引,
//相当于下一个元素的直接索引
arr[count]=stu4;
//添加完成之后,遍历数组打印信息
print_arr(arr);
}
}
//如果数组存满了,那只能扩容在老数组+1
}
public static boolean contains(Student [] arr,int id){
for (int i = 0; i < arr.length; i++) {
Student stu=arr[i];
//获取数组中学生的id
if(stu!=null){
int sid=stu.getId();
if ( sid==id) {
return true;}
}} return false;
}
public static int get_count(Student[]arr){
int count=0;
for (int i = 0; i < arr.length; i++) {
if ( arr[i]!=null ) {
count++;
}
}
return count;
}
public static Student[] create_arr(Student[] arr){
Student new_arr[]=new Student[arr.length+1];
for (int i = 0; i < arr.length; i++) {
//把老数组复制到新数组
new_arr[i]=arr[i];
}
return new_arr;
}
public static void print_arr(Student[] arr){
for (int i = 0; i < arr.length; i++) {
Student stu=arr[i];
if ( stu!=null ){
System.out.println(arr[i].getId()+" "+arr[i].getName()+" "+arr[i].getAge());
}
}
}
//获取索引
public static int get_index(Student[]arr,int id){
for (int i = 0; i < arr.length; i++) {
//依次获取每一个学生的对象
Student stu=arr[i];
if(stu!=null){
int sid=stu.getId();
if ( sid==id ){
return i;
}
}
}
return -1;
}
}
四、学习面向对象的注意事项:
学习面向对象编程(OOP)时,特别是在Java中,有一些重要的注意事项可以帮助你更好地理解和应用这一编程范式。
1. 理解类和对象:
类是对象的抽象,它定义了对象的结构和行为。
对象是类的具体实例,每个对象都有自己的状态和行为。
2. 合理定义类的属性和方法:
根据需求确定类的特性和行为。
类的属性(字段)用于存储对象的状态。
类的方法用于定义对象的行为。
3. 注意封装性:
将类的内部实现隐藏起来,只暴露必要的接口。
使用访问控制符(如private、protected、public)来控制对类成员的访问。
提供公共的getter和setter方法来访问私有字段。
4. 方法定义:
定义方法时如果有返回值,至少需要有一个有效的return语句。
方法的逻辑应当清晰,尽量避免过长的方法。
5. 代码的可读性和可维护性:
使用有意义的命名约定。
保持代码整洁,遵循良好的编程实践。
添加适当的文档注释。