Java逻辑思维的理解
在前面我们已经学习了不少java的语法,以及其应用方法。那么因此可知,如果要解决的问题十分复杂,可能需要上万行代码,像以前那样把代码全部放在一个java文件内会造成一个问题,那就是难以维护。那么今日就让我们进入面向对象的世界里,学习如何从另一个角度看待世界万物。
一、类和对象逻辑的理解
1.1 对象
1.1.1 对象的理解
如何去理解对象呢?对象其实是一个世界当中的一个具体事物。人们对万事万物的认知过程中把一个个的事物分类总结起来,所以世界可以说是由不同类别的事物构成的。这些一个个的具体事物在你想到它的特征时,就会在脑海里自然的浮现出它的形象。这些客观存在的万事万物中的一个就是对象。在Java的世界中,“万物皆对象”。
1.1.2 对象的解析
既然客观存在的任何事物都可以被看做对象,那么我们首先需要解决的问题就是如何对现实世界的对象进行分析和归纳,与要解决的相关问题有所联系。
Java是一种面向对象的编程语言(Object Oriented Programming Language,OOPL),因此我们需要学会使用面向对象的思维方式考虑问题和编写程序。那对于对象如何区分呢?其实每一个对象都有独有的特征,就像自然界中没有两片相同的叶子。而特征则可以分为静态特征与动态特征。静态特征是可以用文字、数字等数据来描述的特征。动态特征是当前对象所具有的动作、功能。
1.1.3 对象的属性和方法
在限定一个范围内,正是因为对象有了静态特征与动态特征,才能让我们把它与其他东西区分开来。在面向对象的编程思想中,把对象的静态特征与动态特征分别称为对象的“属性”和“方法”,它们是构成对象的两个主要因素。。
对象:用来描述客观事物的一个实体,由一组属性和方法构成。
1.1.4 封装
封装就是把一个事物包装起来,并尽可能的隐藏内部的细节。而对象的属性和方法是不可分割的,它们共同组成了实体对象。因此,对象具有封装性。
1.2 类
1.2.1 什么是类
上文已经解释了什么是对象以及分析对象的属性和方法,但是一个对象的属性或方法并不是唯一的。这只是对象本身这一类中的一个实例,在将这些共同的属性和方法归为一个分类,这就是“类”。
1.2.2 类与对象的关系
类其实是我们用来更好更快的了解世间万物的实体所下的一个***抽象的统一定义***。而实体,也就是所谓的对象,就是这一个类中的一个实例。
1.2.3 类是对象的类型
在以前我们已经学习了不少数据类型,它们非常便于我们使用,在编程数只需声明变量即可。当然,在翻阅了以上文字之后,你应该对类与对象有了一定的了解。那么,如果描述一个现实中的事物,他的数据类型就应当是他所属的这个类。也就是说:类就是对象的类型。
1.3 Java是面向对象的语言
1.3.1 Java的类模板
学习过类与对象的概念后,接下来就应该学习如何在Java中使用它们了。
语法:
public class <类名>{
//定义属性的部分
属性1的类型 属性1;
属性2的类型 属性2;
······
属性n的类型 属性n;
//定义方法的部分
方法1;
方法2;
······
方法n;
}
编写时要注意代码规范,不要漏写public。
类的命名规则:
- 不能使用Java中的关键字。
- 不能包含任何嵌入的空格或点号“.”,以及除下划线“_”、字符“$”外的特殊字符。
- 不能以数字开头。
二、类的无参方法
2.1 类的方法的使用
2.1.1 如何定义类的方法
类的方法必须包括以下三个部分。
- 方法的名称。
- 方法的返回值类型。
- 方法的主体。
语法:
public 返回值类型方法名(){
//方法的主体
}
通常,编写方法时,分两步完成。
第一步:定义方法名和返回值类型。
第二步:在{}中编写方法的主体部分。
在编写方法时,要注意以下三点:
- 方法体放在一对大括号中。方法体就是一段程序代码,完成一定的工作。
- 方法名主要在调用这个方法时使用。在Java中一般采用骆驼命名法。
- 方法执行后可能会返回一个结果,该结果的类型称为返回值类型。使用return语句返回值。
2.1.2 返回值的使用注意
在编写程序时一定要注意方法声明中返回值的类型和方法体中真正返回值的类型是否匹配。如果不匹配,编译器就会报错。return是跳转语句的一种,它主要做两件事情。
- 跳出方法:意思是“我已经完成了,要离开这个方法”。
- 给出结果:如果方法产生一个值,这个值放在return后面,即<表达式>部分,意思是“离开方法,并将<表达式>的值返回给调用它的程序”。
2.1.3 方法调用
在程序中通过使用方法名称从而执行方法中包含的语句,这一过程就称为方法调用。
语法:
对象名.方法名();
类的方法调用,均使用如下两种形式。
- 同一个类中的方法,直接使用方法名调用该方法。
- 不同类的方法,首先创建对象,再使用“对象名.方法名()”来调用。
2.2 如何区分变量
2.2.1 成员变量和局部变量
成员变量和局部变量是在运用类的方法中的两种作用域不同的变量。它们都是变量,只是在使用的过程中需要注意以下两点。
- 成员变量:AutoLion类的方法可以直接使用该类定义的成员变量。如果其他类的方法要访问它,必须首先创建该类的对象,然后才能通过操作符"."来引用。
- 局部变量:它的作用域仅仅在定义该变量的方法内,因此只有在这个方法中才能使用。
总的来说,使用成员变量和局部变量时需要注意一下几点内容
- 作用域不同:局部变量的作用域仅限于定义它的方法,在该方法外无法访问。成员变量的作用域在整个内部都是可见的,所以成员方法都可以使用,如果访问权限允许,还可以在类外部使用成员变量。
- 初始值不同:对于成员变量,如果在类定义中没有给他赋初始值。Java会给他一个默认值。基本数据类型的值为0,引用类型的值为null,但是Java不会给局内变量赋初始值,因此局部变量必须要定义赋值后再使用。
- 在同一个方法中,不允许有同名的局部变量。在不同的方法中,可以有同名的局部变量。
- 局部变量可以和成员变量同名,并且在使用时,局部变量具有更高的优先级。
2.3 JavaDoc 注释的使用
程序是程序员的创作作品,它应该具有可读性、相对持久性和可维护性,否则自己以前的作品在之后的阅读中可能给自己或者他人留下障碍,因此,一定要从一开始就养成写注释的习惯。
示例1
/**
*AccpSchool类
*@author JadeBird
*@version 1.0 2019.9.19
*/
JavaDoc是前Sun公司提供的一种技术,它能够从程序源代码中提取类、方法、成员等的注释,形成一个和源代码配套的API帮助文档(简单那来说,就是介绍该类、类的方法和成员变量的文档)。
JavaDoc注释的语法规则:
- JavaDoc注释以"/**“开头,以”*/"结尾。
- 每个注释包含一些描述性的文本及若干个JavaDoc标签。
- JavaDoc标签一般以"@"为前缀,常用的JavaDoc标签如下图所示
标签 | 含义 |
---|---|
@author | 作者名 |
@parameter | 参数及其意义 |
@return | 返回值 |
@version | 版本标识 |
@since | 最早使用该方法/接口的JDK版本 |
@throws | 异常类及抛出条件 |
三、带参数的方法
3.1 带参方法的使用
3.1.1 定义带参方法
语法:
<访问修饰符> 返回值类型 <方法名> (<参数列表>){
//方法的主体
}
在语法中:
- <访问修饰符>指该方法允许被访问的权限范围,只能是public、protectd或private。
- 返回值类型指方法返回值的类型。如果方法不返回任何值,他应该声明为void类型。Java对待返回值的要求很严格,方法返回值必须与所说明的类型相匹配。使用return语句返回值。
- <方法名>是定义的方法和名字,它应该使用合法的标识符。
- <参数列表>是传送给方法的参数列表。列表中各参数间以逗号分隔。
示例2
public class StudentsBiz{
String[] names = new String[30];
public void addName(String name){
//增加学生姓名
}
}
类中的属性可以是单个变量,亦可以是一个数组形参和实参。形参是在调用方法时对参数的称呼,实参是在调用方法时传递给方法处理的实际的值。
调用方法时,需要注意以下两点:
- 先实例化对象,再调用方法。
- 实参的类型、数量、顺序都要与形参一一对应。
3.1.2 调用带参方法
调用带参方法与无参方法语法基本相同,但是在调用带参方法时必须传入实际的参数的值。
语法:
对象名.方法名(参数1,参数2,....参数n);
在定义方法和调用方法时,把参数分别称为形式参数和实际参数,简称是在定义方法时对参数的称呼,目的是定义方法需要传入的参数个数和类型。实参是在调用方法时传递给方法处理的实际的值。
在调用方法时,需要注意以下两点:
- 先实例化对象,再调用方法。
- 实参的类型、数量、顺序都要与形参一一对应。
示例3
public class TestAdd {
public static void main(String[] args) {
StudentsBiz st = new StudentsBiz();
Scanner in = new Scanner(System.in);
for (int i = 0; i < 5; i++) {
System.out.println("请输入学生姓名:");
String newName = in.next();
st.addName(newName);
}
st.showNames();
}
}
3.2 深入理解带参方法
3.2.1 带多个参数的方法
public class searchName {
public boolean searchName(int start,int end,String name, Object[] names) {
boolean find = false;
for (int i = start-1; i < end; i++) {
if(names[i].equals(name)) {
find = true;
break;
}
}
return find;
}
}
带参方法的参数个数无论错少,在使用时只要注意实参和形参一一对应,传递的实参值与形参的数据类型相同、个数相同、顺序一致,就掌握了带参方法的使用。
3.2.2 数组作为参数的方法
示例4
public class StudentsBiz2 {
/**
* 求平均分
* @param scores 参赛成绩数组
* @return
*/
public double calAvg(int[] scores) {
int sum = 0;
double avg = 0.0;
for (int i = 0; i < scores.length; i++) {
sum += scores[i];
}
avg = (double)sum/scores.length;
return avg;
}
/**
* 求最高分
* @param scores 参赛成绩数组
* @return
*/
public int calMax(int[] scores) {
int max = scores[0];
for (int i = 1; i < scores.length; i++) {
if(max<scores[i]) {
max = scores[i];
}
}
return max;
}
}
public class TestCal {
public static void main(String[] args) {
StudentsBiz2 st = new StudentsBiz2();
int[] scores = new int[5];
Scanner in = new Scanner(System.in);
System.out.println("请输入五名参赛者的成绩:");
for (int i = 0; i < 5; i++) {
scores[i] = in.nextInt();
}
double avgScores = st.calAvg(scores);
System.out.println("平均成绩:"+avgScores);
int maxScore = st.calMax(scores);
System.out.println("最高成绩:"+maxScore);
}
}
示例4中的类定义了两个方法,分别实现了求平均成绩和最高成绩。它们都是带数组参数并且带返回值的方法。
public double calAvg(int[] scores);
public int calMax(int[] scores);
参数scores数组传递所有学员的比赛成绩,而且定义方法时并没有指定数组大小,而是在调用方法时确定要传递的数组的大小。return语句用来返回平均成绩和最高成绩。
3.2.3 对象作为参数的方法
示例5
public class Student {
int id;
String name;
int age;
int score;
public void showInfo() {
System.out.println(id+"\t"+name+"\t"+age+"\t"+score);
}
}
public class StudentsBiz3 {
Student[] students = new Student[30];
public void addStudent(Student stu) {
for (int i = 0; i < students.length; i++) {
if(students[i] == null) {
students[i] = stu;
break;
}
}
}
public void showStudents() {
System.out.println("本班学生列表:");
for (int i = 0; i < students.length; i++) {
if(students[i] != null) {
students[i].showInfo();
}
}
System.out.println();
}
}
调用该方法的代码如下:
public class TestAddd {
public static void main(String[] args) {
Student student1 = new Student();
student1.id = 10;
student1.name = "王紫";
student1.age = 18;
student1.score = 99;
Student student2 = new Student();
student2.id = 11;
student2.name = "郝田";
student2.age = 19;
student2.score = 60;
StudentsBiz3 studentsBiz = new StudentsBiz3();
studentsBiz.addStudent(student1);
studentsBiz.addStudent(student2);
studentsBiz.showStudents();
}
}
在示例5中,Student[] students = new Student[30];表示声明了大小为30的学生对象数组,即数组students可以存储30个学生对象。方法带有一个Student类型 参数,调用时将传递一个学生对象。就传递的参数而言,这里的Student类型的参数与前面学习的int、String等类型的参数相同,需要保证形参与实参的一致。
3.3 包的说明
3.3.1 为什么需要包
包主要有以下三个方面的作用:
- 包允许将类组合成较小的单元(类似文件夹),易于找到和使用相应的类文件。
- 防止类名冲突:Java中只有在不同包中的类才能重名。
- 包允许在更广的范围内保护类、数据和方法,可以在包内定义类。根据规则,包外的代码有可能不能访问该类。
3.3.2 如何声明包
要声明一个包,只要包含一个package命令作为一个Java源文件的第一条语句就可以。
示例6
public class AccpSchool {
//..........
public String toString() {
//..........
return null;
}
}
package是关键字。包的声明必须是Java源文件中的第一条非注释类语句,而且一个源文件只能有一个包声明语句。Java中,包被设计与文件系统结构相对应。因此,在命名包时,要严格遵守以下编码规范:
- Java包的名字通常由小写字母组成,不能以圆点开头或结尾。
- 一个唯一包名的前缀通常是全部小写的ASCII字母,并且是一个顶级域名com、edu、gov、net或org。通常使用知足的网络域名的逆序。
- 包名的后续部分依不同机构各自内部的规范不同而不同。这类命名规范可能以特定目录名的组成来区分部门、项目、机器或注册名。
3.3.3 如何导入包
要使用不在同一个包中的类,需要将包显式地包括在Java程序中。在Java中,使用关键字import告知编译器所要使用的类位于哪一个包中,这个过程称为导入包。
语法:
import java.util.*;
import 包名.类名;
这里的包名可以是系统提供的包,也可以是自己定义的包。
示例6
package cn.jbit.classandobject;
public class AccpSchool2 {
public void showMessage() {
System.out.println("这是上海Accp中心。");
}
}
声明包的含义:声明当前类所处的位置。
导入包的含义:声明在当前类中要使用到的其他类所处的位置。
四、字符串应用方法
4.1 字符串的具体说明
4.1.1 如何使用字符串
简单地说,使用字符串主要分为两步:
- 定义并初始化字符串。
- 使用字符串,对字符串进行一些处理。
示例7
String s = "Hello World";
String s = new String();
4.1.2 字符串的长度
String类提供了length()方法。字符串是一串字符序列,String类的length()方法用来确定字符串的长度,即字符串中的字符数目。调用length()方法返回的结果就是字符串中的字符数。
示例8
public class Register {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String uname,pwd;
System.out.println("请输入用户名:");
uname = in.next();
System.out.println("请输入密码:");
pwd = in.next();
if(pwd.length()>=6) { //判断密码长度
System.out.println("注册成功!");
} else {
System.out.println("密码长度不能小于6位!");
}
}
}
4.1.3 字符串的比较
在使用eruals()方法比较两个字符串时,它逐个对照组成两个字符串的每个字符是否相同。如果都相同,则返回true;否则返回false。对于字符的大小写,也在检查范围之内。
示例9
public class Login {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
String uname,pwd;
System.out.println("请输入用户名:");
uname = in.next();
System.out.println("请输入密码:");
pwd = in.next();
if(uname.equals("TOM") && pwd.equals("1234567")) {
System.out.println("登陆成功!");
} else {
System.out.println("用户名与密码不匹配,登录失败!");
}
}
}
在Java中,双等号“= =”和equals()方法虽都应用于两个字符串,但所判断的内容是有差别的。简单地讲,"= ="判断的是两个字符串对象在内存中的首地址是否相等,即判断是否是同一个字符串对象,而equals()判断的是两个字符串对象是否相等。但是equals()方法在判断时并不会忽略大小写,因此这时需要用到另一种方法——equalslgnoreCase()方法。lgnore是忽略的意思,这种方法在比较字符串时会忽略字符的大小写。
当然在Java中,String类也提供了两个方法改变字符串中字符的大小写。
- toLowerCase():转换字符串的英文字母为小写。
- toUpperCase():转换字符串的英文字母为大写。
4.2 复杂字符串的处理方法
4.2.1 字符串的连接
示例10
public class PrintScore {
public static void main(String[] args) {
int sqlScore = 80;
int javaScore = 90;
double htmlScore = 86.7;
String scoreSheet = "SQL:"+sqlScore+"\t"+"Java:"+javaScore+"\t"+"HTML:"+htmlScore;
System.out.println("*****成绩单*****");
System.out.println(scoreSheet);
}
}
创建字符串对象时,使用运算符"+“将多个字符串连接成一个新字符串,并且使用”+“可以将任意多个字符串连接在一起。而且,在使用”+“运算符连接字符串和int(或double)类型数据时,”+"将int(或double)类型数据自动转换成String类型。除此之外,String类也提供了另一个方法concat(),将一个字符串连接到另一个字符串的后面。
语法:
字符串1.concat(字符串2);
4.2.2 字符串的提取和查询
序号 | 方法 | 说明 |
---|---|---|
1 | Public int indexOf(int ch)Public int indexOf(String value) | 搜索第一个出现的字符或字符串 |
2 | Public int lastindexOf(int ch)Public int lastindexOf(String value) | 搜索最后一个出现的字符或字符串 |
3 | Public Sreing substring(int index) | 提取从位置索引开始的字符串部分 |
4 | Public String substring(int beginindex,int endindex) | 提取beginindex和endindex之间的字符串部分 |
5 | Public String trim() | 返回一个前后不含任何空格的调用字符串的副本 |
字符串是一个字符序列,每一个字符都有自己的位置,字符串事实上也是一个字符数组,因此它的位置从0开始到(字符串长度-1)结束。
可见,要想在程序中处理好字符串,关键是将这些方法巧妙地结合起来,灵活运用。
示例11
public class Verify {
public static void main(String[] args) {
boolean fileCorrect = false;
boolean emailCorrect = false;
System.out.println("---欢迎进入作业提交系统---");
Scanner in = new Scanner(System.in);
System.out.println("请输入Java文件名:");
String fileName = in.next();
System.out.println("请输入你的邮箱:");
String email = in.next();
int index = fileName.lastIndexOf(".");
if(index != -1 && index != 0 && fileName.substring(index+1,fileName.length()).equals("java")) {
fileCorrect = true;
} else {
System.out.println("文件名无效。");
}
if(email.indexOf('@') != -1 && email.indexOf('.') > email.indexOf('@')) {
emailCorrect = true;
} else {
System.out.println("E-mail无效。");
}
if(fileCorrect && emailCorrect) {
System.out.println("作业提交成功!");
} else {
System.out.println("作业提交失败!");
}
}
}
判断Java文件名是否有效时,使用的判断条件如下:
index != -1 && index != 0 && fileName.substring(index+1,fileName.length()).equals("java")
4.2.3 字符串的拆分
语法:
字符串1.split(String separator,int limit);
其中:
- separator可选项,标识拆分字符串时使用一个或多个字符。如果不选择该项,则返回包含该字符串所有单个字符的元素数组。
- limit可选项,该值用来限制返回数组中的元素个数。
示例13
public class Lyric {
public static void main(String[] args) {
String words = "长亭外 古道边 芳草碧连天 晚风扶 柳笛声残 夕阳山外山";
String[] printword = new String[100];
System.out.println("***原歌词格式***\n"+words);
System.out.println("\n***拆分后歌词格式***");
printword = words.split(" ");
for (int i = 0; i < printword.length; i++) {
System.out.println(printword[i]);
}
}
}
4.3 StringBuffer 类的使用
4.3.1 如何使用StringBuffer类
StringBuffer类位于java.lang包中,是String类的增强类。使用StringBuffer类也需要两步完成。
1.声明StringBuffer对象并初始化
示例14
//声明一个空的StringBuffer对象
StringBuffer sb1 = new StringBuffer();
//声明一个字符串"青春无悔"
StringBuffer sb2 = new StringBuffer("青春无悔");
2.使用StringBuffer对象
StringBuffer类提供了很多方法以供使用,调用时使用"."操作符完成。
4.3.2 常用的StringBuffer类方法
语法:
字符串1.toString();
将StringBuffer类型的字符串1转换为String类型的对象并返回。
语法:
字符串1.append(字符串2);
将字符串2连接到字符串1后并返回。该方法和String类的concat()方法一样,都是把一个字符串追加到另一个字符串后面,所不同的是String中只能将String类型的字符串追加到一个字符串后,而StringBuffer可以将任何类型的值追加到字符串之后。
示例15
public class sbAppend {
public static void main(String[] args) {
StringBuffer sb = new StringBuffer("青春无悔");
int num = 110;
StringBuffer sb1 = sb.append("我心永恒");
System.out.println(sb1);
StringBuffer sb2 = sb1.append('啊');
System.out.println(sb2);
StringBuffer sb3 = sb2.append(num);
System.out.println(sb3);
}
}
语法:
字符串1.insert(位置,参数);
将参数插入字符串1的指定位置(int 类型)后并返回。参数可以是包括String的任何类型。
示例16
public class TestInsert {
public static void main(String[] args) {
Scanner in = new Scanner(System.in);
System.out.println("请输入一串数字:");
String nums = in.next();
StringBuffer str = new StringBuffer(nums);
for (int i = str.length()-3; i >0; i= i-3) {
str.insert(i,',');
}
System.out.println(str);
}
}
4.3.3 总结
String
获得字符串长度:length()
比较字符串:equals()
连接字符串:concat()
提取字符串:substring()
搜索字符串:indexOf()
拆分字符串:split()
StringBuffer
转换成String类型:toString()
连接字符串:append()
插入字符串:insert()
五、感言
java中类和对象的逻辑的理解是非常重要的,这决定了接下来的继续深入学习java时最终的高度与效率。另外,在本篇中字符串的语法并未完全展示,详细资料可以参考“javaAPI”。里面有全面的语法可供查阅参考。