1、基础常识
1.1、软件开发
软件:
一系列按照特定顺序组织的计算机数据和指令的集合。
常见的软件:
- 系统软件:DOS,windows,Linux等。
- 应用软件:扫雷,迅雷,QQ等。
- 开发:制作软件。
1.1.2、人机交互
交互方式:
- 1、图形化界面:这种方式简单直观,使用者易于接受,容易上手操作。
- 2、命令行方式:需要有一个控制台,输入特定的指令,让计算机完成一些操作。
1.1.3、常用的DOS命令
常见的命令:
- dir :列出当前目录下的文件以及文件夹
- md:创建目录
- rd:删除目录
- cd:进入指定的目录
- cd/:退回到根目录
- del:删除文件
- exit:推出dos命令行
1.2、Java语言概述
1.2.1、Java语言的三种技术架构
- J2EE
- J2SE
- J2ME
1.2.2、Java语言的特点
特点:
- 跨平台性
所谓的跨平台性,是指软件可以不受计算机硬件和操作系统的约束而在任意计算机环境下正常运行。这是软件发展的趋势和编程人员追求的目标。之所以这样说,是因为计算机硬件的种类繁多,操作系统也各不相同,不同的用户和公司有自己不同的计算机环境偏好,而软件为了能在这些不同的环境里正常运行,就需要独立于这些平台。而在Java语言中,java自带的虚拟机很好地实现了跨平台性。 Java源程序代码经过编译后生成二进制的字节码是与平台无关的,但是可被Java虚拟机识别的一种机器码指令。 Java虚拟机提供了一个字节码到底层硬件平台及操作系统的屏障,使得Java语言具备跨平台性。
2. 面向对象
面向对象是指以对象为基本粒度,其下包含属性和方法。对象的说明用属性表达,而通过使用方法来操作这个对象。面向对象技术使得应用程序的开发变得简单易用,节省代码。Java是一种面向对象的语言,也继承了面向对象的诸多好处,如代码扩展、代码复用等。
3. 安全性
安全性可以分为四个层面,即语言级安全性、编译时安全性、运行时安全性、可执行代码安全性。语言级安全性指Java的数据结构是完整的对象,这些封装过的数据类型具有安全性。编译时要进行Java语言和语义的检查,保证每个变量对应一个相应的值,编译后生成Java类。运行时Java类需要类加载器载入,并经由字节码校验器校验之后才可以运行。 Java类在网络上使用时,对它的权限进行了设置,保证了被访问用户的安全性。
4. 多线程
多线程在操作系统中已得到了最成功的应用。多线程是指允许一个应用程序同时存在两个或两个以上的线程,用于支持事务并发和多任务处理。 Java除了内置的多线程技术之外,还定义了一些类、方法等来建立和管理用户定义的多线程。
5. 简单易用
Java源代码的书写不拘泥于特定的环境,可以用记事本、文本编辑器等编辑软件来实现,然后将源文件进行编译,编译通过后可直接运行,通过调试则可得到想要的结果。
原理:
只要在需要运行Java应用程序的操作系统上,先安装一个Java虚拟机即可。由JVM来负责Java程序在该系统中的运行。
1.3、Java语言的环境搭建
步骤:
- 明确什么是JRE,JDK
- 下载JDK
- 安装JDK
- 配置环境变量
- 验证是否成功
注意:
想要永久性的配置环境变量需要在我的电脑的属性的高级选项中进行配置;若只是需要临时配置则在dos窗口进行指令配置,如set path=HelloWorld,
且该指令仅在该dos窗口有效,如果新建一个dos,则不生效。
1.4、Java程序开发体验–HelloWorld
步骤:
- 1.4.1、将java代码编写到扩展名为.java的文件中。
- 1.4.2、通过javac命令对该java文件进行编译。
- 1.4.3、通过java命令对生成的class文件进行运行。
如:
class HelloWorldTest
{
public static void main(String[] args)
{
System.out.println("HelloWorld");
}
}
1.5、classpath配置
-
形如:set classpath=d:\表示只在c盘寻找目标文件。
-
形如:set classpath=d:\;则表示若在盘寻找不到目标文件,还会在当前目录下找。
2、 Java语言基础组成
2.1 关键字
- 定义:被Java语言赋予了特殊的含义的单词
- 特点:关键字中所有字母都为小写
2.2 标识符
1、 定义:由26个英文字母大小写,数字:0-9符号:_$组成
2、 定义合法标识符规则:
- 数字不可以开头。
- 不可以使用关键字。
注意:java中严格区分大小写
2.3. 注释
2.3.1、单行注释
形如:
//这是我的HelloWorld程序
2.3.2、多行注释
形如:
/*这是我的HelloWorld程序*/
2.3.3、文档注释
形如
/**
*这是我的HelloWorld程序
*/
2.4、类型转换
形如 byte b = 3;
b = b + 2:,不同的类型进行运算,需要进行强制转换。
即,b = (byte) (b + 2); //对b + 2的结果进行强制转换为byte型。
注意:
不同的类型进行运算,转换的类型也不同,如:
System.out.println(‘a’);输出结果为 a,
System.out.pritnln(‘a’+1);输出结果为97,字符型和整形进行运算,结果为整形。
2.5 、运算符
- 算数运算符,形如 :+、-、/、*等等
- 赋值运算符,如:=
- 比较运算符,
如:==、><等等 - 逻辑运算符,如:or、not、and等等
- 位运算符,如:按位与(&)、按位或(or)、按位异或(^)、按位取反(~)等等
- 三元运算符,如名字表示的三元运算符需要三个操作数。
语法为:条件表达式?表达式1:表达式2。
说明:问号前面的位置是判断的条件,判断结果为bool型,为true时调用表达式1,为false时调用表达式2。
其逻辑为:“如果为条件成立或者满足则执行表达式1,否则执行第二个。”常用在设置默认值,例如某个值不一定存在,则判断这个值是否存在,不存在给默认值(表达式2)
注意&与&&的特点:
&:无论左边是true还是false,右边都运算。
&&:当左边为false时,右边不运算。
“|” 和 “||” 特点与上类似。
2.6、程序流程控制
2.6.1、判断结构
1、if 语句
if (条件表达式) {
//执行语句;
}
2、if … else … 语句
if (条件表达式) {
//执行语句;
} else {
//执行语句;
}
3、if … else if … else 语句
if (条件表达式) {
//执行语句;
} else if (条件表达式) {
//执行语句;
} else {
//执行语句;
}
- 三元运算符:
好处:可以简化if else 代码。
弊端:因为是一个运算符,所以运算完必须要有一个结果。
- 注意:
1、if else 运算不需要结果
2、if else 结构简写格式:变量=(条件表达式)?表达式1:表达式2;
2.6.2、选择结构
switch语句
如:
swith (表达式) {
case 取值1;
执行语句;
break;
case取值2;
执行语句;
break;
......
defalut
执行语句;
break;
}
2.6.3、循环结构
代表语句:while, do while , for
具体句式:
1、while语句格式:
while (条件表达式) {
//执行语句;
}
2、do while语句格式:
do {
//执行语句;
} while (条件表达式 );
3、for语句
for语句格式:
for(初始化表达式;循环体条件表达式;循环后的操作表达式){
//执行语句;
}
注意:
1、do while 语句无论条件是否成立,循环体至少执行一次,而while语句当条件不满足时不会执行。
2、在for语句内定义的循环变量仅在该语句中生效,离开该语句后,该循环变量在内存中就消失了;而对于while语句,循环变量在语句外定义,该循环变量在循环外依然存在。因此变量只为循环增量而存在时,采用for语句更合适。
2.6.4、其他流程控制语句
break (跳出)
应用于选择结构和循环结构,如:switch,if,for等语句。
continue(继续)
应用于循环结构,如for,while,do…while等语句。
注:
a.这两个语句离开应用范围,存在是没有意义的。
b.这两个语句单独存在下面都可以有语句,因为执行不到。
c.continue语句是结束本次循环继续下次循环,break是结束整个循环。
d.标号的出现,可以让这两个语句作用于指定的范围。
验证c有以下代码
class OtherTest {
public static void main(String[] args) {
//break;
for(int y = 0; y < 4; y++) {
System.out.println("y = " + y);
break;
}
//continue;
for(int x = 0; x < 4; x++) {
if(x == 3)
continue;
System.out.println("x = " + x);
}
}
}
输出结果为:
y = 0
x = 0
x = 1
x = 2
2.7、函数
2.7.1、函数的定义
- 什么是函数
函数就是定义在类中的具体特定功能的一段独立小程序。
函数也称为方法。
- 函数的格式:
修饰符 返回值类型 函数名(参数类型 形式参数1,参数类型 形式参数2,......){
//执行语句;
return 返回值;
}
如下面是一个简单的计算两个数的和的函数:
public static double sum(double x,double y) {
return x + y;
}
注意:
public static代表是静态方法,可以不通过创建所属对象进行访问;直接public代表是非静态方法,需要先new一个对象进行访问。通常情况下,类成员必须通过它的类的对象访问,但是可以创建这样一个成员,它能够被它自己使用,而不必引用特定的实例。在成员的声明前面加上关键字static(静态的)就能创建这样的成员。
2.7.2、函数的特点
1、定义函数可以将功能代码进行封装
2、便于对该功能进行复用
3、函数只有被调用才会被执行
4、函数的出现提高了代码的复用性
5、对于函数没有具体返回值的情况,返回值类型用关键字void表示,那么该函数中的return语句如果在最后一行可以省略不写。
注意:
函数中只能调用函数,不可以在函数内部定义函数。
定义函数时,函数的结果应该返回给调用者,交由调用者处理。
2.7.3、函数的应用
- 两个明确
1、明确要定义的功能最后的结果是什么?
2、明确在定义该功能的过程中,是否需要未知内容参与运算
- 示例
1、需求:定义一个功能,可以实现两个数的加法运算。
2、分析:
(1)该功能的运算结果是什么?两个数的和,也是一个正整数
(2)在实现该功能的过程中是否有关未知内容参与运算?两个加数有键盘输入,是不确定的,类型为int型。
- 具体代码如下
import java.util.Scanner;//导入键盘录入的类 Scanner
class SumTest {
public static void main(String[] args) {
//创建键盘录入类Scanner的对象
Scanner sc = new Scanner(System.in);
System.out.println("请输入第一个正整数:");
//通过对象sc调用Scanner类中的nextInt()方法读取输入的数据并进行存储
int num1 = sc.nextInt();
System.out.println("请输入第二个正整数:");
int num2 = sc.nextInt();
//函数的调用:定义一个int型的变量来接受和
int sum = add(num1, num2);
System.out.println("sum = " + sum);
}
//求和函数
public static int add(int a, int b) {
return a + b;
}
}
输出结果为:
请输入第一个正整数:
23
请输入第二个正整数:
13
sum = 36
注:
java中最小的功能单元就是函数,函数是包含具体功能的独立模块,在编写好的函数内部进行结果的输出是不好的,如:
public static void get(int a, int b) {
System.out.println(a + b);
return;
}
结果的输出应根据调用者的需求在主函数内进行输出。
2.7.4、函数的重载
- 重载的概念
在同一个类中,允许存在一个以上的同名函数,只要它们的参数个数或者参数类型不同即可。
- 重载的特点
与返回值无关,只看参数列表。
- 重载的好处
方便阅读,提高代码的复用性,优化了程序设计。
- 重载示例
1、返回两个整数的和
int add(int x, int y) {
return x + y;
}
2、 返回三个整数的和
int add(int x, int y, int z)
{
return x + y + z;
}
3、返回两个小数的和
double add(double x, double y) {
return x + y;
}
- 注意:
参数列表里的参数是有顺序的如:
a、void show(int a, char b, double c) {}
b、void show(int x, double y, char z) {}
上面的b函数重载了a函数,因为对应的参数类型不一致,与顺序有关。
2.8、数组
2.8.1、 数组的定义
1、概念
同一种类型数据的集合,其实数组就是一个容器。
2、数组的好处
可以自动给数组中的元素从0开始编号,方便操作这些元素。
3、格式
- 格式1(动态方式)
元素类型[] 数组名=new 元素类型[元素个数或数组长度];
示例:int[] arr=new int[5];
- 格式2(静态方式)
元素类型[] 数组名=new 元素类型[]{元素,元素,…}
示例:int[] arr=new int[]{3,5,1,7};
int arr={3,5,1,7};
注意:
1.如果使用静态方式创建数组,那么系统会根据元素的个数自动计算数组的长度。
2.静态方式创建数组右边的中括号里面不能写长度。
3.静态方式的省略格式创建数组不能先声明后赋值,只能声明的同时直接赋值。
2.8.2、数组的内存分配及特点
1、栈内存(特点:会自动释放内存)
2、堆内存(特点:不会自动释放内存)
注:
堆内存中存在默认初始值,具体值与定义的类型有关,
如int型的默认值是0,double型的默认值是0.0。
2.8.3、数组操作常见问题
1、数组的下标越界,编译时不会出错,但运行时会出错。
如:
int[] arr = new int[3];
System.out.println(arr[3]);
运行错误提示:ArrayIndexOutOfBoundException
2、空指针异常
如:
int[] arr = new int[3];
arr = null;
System.out.println(arr[1]);
错误提示:NullPointerException
2.8.4、数组常见操作
1、获取数组中的元素(通常会用到遍历)如:
int[] arr = new int[3];
for(int x = 0; x < 3; x++) {
System.out.println("arr[" + x + "]" = arr[x] + ";");
}
2、求数组元素的个数,如:
int[] arr = new int[3];
System.out.println("length=" + arr.length);
3、面向对象
3.1、关于面向对象
概念:
面向对象(Object Oriented,OO)是软件开发方法。面向对象的概念和应用已超越了程序设计和软件开发,扩展到如数据库系统、交互式界面、应用结构、应用平台、分布式系统、网络管理结构、CAD技术、人工智能等领域。面向对象是一种对现实世界理解和抽象的方法,是计算机编程技术 [1] 发展到一定阶段后的产物。
特征:
(1)唯一性。
每个对象都有自身唯一的标识,通过这种标识,可找到相应的对象。在对象的整个生命期中,它的标识都不改变,不同的对象不能有相同的标识。
(2)抽象性。
抽象性是指将具有一致的数据结构(属性)和行为(操作)的对象抽象成类。一个类就是这样一种抽象,它反映了与应用有关的重要性质,而忽略其他一些无关内容。任何类的划分都是主观的,但必须与具体的应用有关。
(3)继承性。
继承性是子类自动共享父类数据结构和方法的机制,这是类之间的一种关系。在定义和实现一个类的时候,可以在一个已经存在的类的基础之上来进行,把这个已经存在的类所定义的内容作为自己的内容,并加入若干新的内容。
继承性是面向对象程序设计语言不同于其它语言的最重要的特点,是其他语言所没有的。
在类层次中,子类只继承一个父类的数据结构和方法,则称为单重继承。
在类层次中,子类继承了多个父类的数据结构和方法,则称为多重继承。
多重继承,JAVA、VB、NET、Objective-C均仅支持单继承,注意在C++多重继承时,需小心二义性。
在软件开发中,类的继承性使所建立的软件具有开放性、可扩充性,这是信息组织与分类的行之有效的方法,它简化了对象、类的创建工作量,增加了代码的可重用性。
采用继承性,提供了类的规范的等级结构。通过类的继承关系,使公共的特性能够共享,提高了软件的重用性。
(4)多态性(多形性)
多态性是指相同的操作或函数、过程可作用于多种类型的对象上并获得不同的结果。不同的对象,收到同一消息可以产生不同的结果,这种现象称为多态性。
多态性允许每个对象以适合自身的方式去响应共同的消息。
多态性增强了软件的灵活性和重用性。
3.2、类与对象的关系
关系:
对象是类的实例,类是对象的模板。对象是通过new className产生的,用来调用类的方法;类的构造方法 。
如: 教师是个类,张三老师就是教师的一个对象。
对象的创立,如:
Person person1, person2;
Car c = new Car();
其中Person为类名,person1,person2为Person的对象。
注:
1、形如:
new Car().num = 5;
new Car().color = "blue";
new Car().run();
为匿名对象,且这三句话只有第三句有意义,这说明匿名对象调用属性是没有意义的,调用方法有运行内容的存在,是有意义的。
2、形如:
Car c = new Car();
c.num = 5;
c.color = "blue";
c.run();
为有名对象。
3、匿名对象使用方式:
(1)、当对象的方法只调用一次时,可以用匿名对象来完成,这样写比较简化;如果对一个对象进行多个成员的调用,必须给这个对象起个名字。
(2)、可以将匿名对象作为实际参数进行传递。
如show(new Car());
下面是一个关于汽车类的简单程序,具体代码如下:
class Test1 {
public static void main(String[] args) {
Car c = new Car();
c.show(c);
}
}
class Car {
int num;
String color;
public static void show(Car c) {
c.num = 5;
c.color = "black";
System.out.println("Car's num=" + c.num + " Car's color is "+c.color);
}
}
输出结果为:
Car's num = 5 Car's color is black
3.3、封装
1、概念:是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
2、好处:
(1)将变化隔离;
(2)便于使用;
(3)提高重用性;
(4)提高安全性。
3、封装原则:
(1)将不需要对外提供的内容都隐藏起来;
(2)把属性都隐藏,提供公共方法对其访问。
为保证类的封装性,可以使用一些特殊的修饰符(private , public , protected)对成员变量和成员函数进行修饰,如:
private int age;
private static void max(int a, int b);
注意:封装不一定是私有,私有仅仅是封装的一种表现形式,不私有也可以实现封装性。
3.4、构造函数
特点:
(1)函数名与类名相同;
(2)不用定义返回值类型;
(3)没有具体返回值。
作用:给对象进行初始化。
注意:
1、默认构造函数:
(1)当一个类中没有定义过构造函数,那么该类中会自动有一个默认的空参数构造函数。
(2)如果在类中定义了指定的构造函数,那么类中的默认构造函数就没有了。
如:
class Person {
Person() {} //定义了一个默认构造函数,而且是空参数的
}
2、多个构造函数是可以以重载的形式存在的。
3、对象一建立,就会调用与之对应的构造函数。
4、默认构造函数只能执行一次。
5、如果在一个类中构造了一个代码块,在创建对象时,会先执行该代码块,再去执行构造函数,如:
class Person {
private String name;
private int age;
{
System.out.println("person code run");
}
Person() {
System.out.println("person run");
}
}
class LIXAIN1 {
public static void main(String[] args) {
Person p1 = new Person();
}
}
输出结果为:
person code run
person run
3.5、this关键字
应用:
1、引用当前类的实例变量
this关键字可用于引用当前的类实例变量。如果实例变量和参数之间存在歧义,则此关键字可解决歧义问题。
(1)未使用this关键字
class Student {
int rollno;
String name;
float fee;
Student(int rollno, String name, float fee) {
rollno = rollno;
name = name;
fee = fee;
}
void display() {
System.out.println(rollno + " " + name + " " + fee);
}
}
class TestThis1 {
public static void main(String args[]) {
Student s1 = new Student(111, "ankit", 5000f);
Student s2 = new Student(112, "sumit", 6000f);
s1.display();
s2.display();
}
}
运行结果:
0 null 0.0
0 null 0.0
(2)使用this关键字
class Student {
int rollno;
String name;
float fee;
Student(int rollno, String name, float fee) {
this.rollno = rollno;
this.name = name;
this.fee = fee;
}
void display() {
System.out.println(rollno + " " + name + " " + fee);
}
}
class TestThis2 {
public static void main(String args[]) {
Student s1 = new Student(111, "ankit", 5000f);
Student s2 = new Student(112, "sumit", 6000f);
s1.display();
s2.display();
}
}
运行结果:
111 ankit 5000
112 sumit 6000
2、调用当前的类方法
您可以使用this关键字调用当前类的方法。如果不使用this关键字,编译器会在调用方法时自动添加此关键字。
class A {
void m() {
System.out.println("hello m");
}
void n() {
System.out.println("hello n");
this.m();
}
}
class TestThis4 {
public static void main(String args[]) {
A a = new A();
a.n();
}
}
}
运行结果:
hello n
hello m
3、调用当前的类构造函数
this() 构造函数调用可用于调用当前的类构造函数。它用于重用构造函数。换句话说,它用于构造函数链接。
class A {
A() {
System.out.println("hello a");
}
A(int x) {
this();
System.out.println(x);
}
}
class TestThis5 {
public static void main(String args[]) {
A a = new A(10);
}
}
4、在方法中作为参数传递
this关键字也可以作为方法中的参数传递。它主要用于事件处理。如,
class S2 {
void m(S2 obj) {
System.out.println("method is invoked");
}
void p() {
m(this);
}
public static void main(String args[]) {
S2 s1 = new S2();
s1.p();
}
}
运行结果:
method is invoked
5、在构造函数调用中作为参数传递
我们也可以在构造函数中传递this关键字。如果我们必须在多个类中使用一个对象,这将非常有用。
class B {
A4 obj;
B(A4 obj) {
this.obj = obj;
}
void display() {
System.out.println(obj.data);//using data member of A4 class
}
}
class A4 {
int data = 10;
A4() {
B b = new B(this);
b.display();
}
public static void main(String args[]) {
A4 a = new A4();
}
}
运行结果:
10
6、用于返回当前的类实例
class A {
A getA() {
return this;
}
void msg() {
System.out.println("Hello java");
}
}
class Test1 {
public static void main(String args[]) {
new A().getA().msg();
}
}
运行结果:
Hello java
注意:对构造函数进行初始化,不能下面这样
Person(name);
可以这样
this(name);
3.6、static关键字
- 作用
用于修饰成员(成员变量和成员函数)
- 被修饰后的成员具备以下特点
(1)随着类的加载而加载;
(2)优先对象存在;
(3)被所有对象所共享;
(4)可以直接被类名调用。
- 使用注意
(1)静态方法只能访问静态成员;
(2)静态方法不可以写this,super关键字;
(3)主函数是静态的。
注:静态有利有弊
利处:对对象的共享数据进行单独空间的存储,节省空间,没有必要每一个对象中都存储一份,可以直接被类名调用。
弊端:生命周期过长,访问出现局限性。(只能访问静态)
3.7、单例设计模式
1、什么是设计模式
设计模式(Design pattern)是一套被反复使用、多数人知晓的、经过分类编目的、代码设计经验的总结。
2、为什么会有单例设计模式
单例模式主要是为了避免因为创建了多个实例造成资源的浪费,且多个实例由于多次调用容易导致结果出现错误,而使用单例模式能够保证整个应用中有且只有一个实例。
3、单例模式的设计思想
保证对象的唯一性,需做好以下三步:
(1)、不允许其他程序用new对象。
因为new就是开辟新的空间,在这里更改数据只是更改的所创建的对象的数据,如果可以new的话,每一次new都产生一个对象,这样肯定保证不了对象的唯一性。
(2)、在该类中创建对象
因为不允许其他程序new对象,所以这里的对象需要在本类中new出来
(3)、对外提供一个可以让其他程序获取该对象的方法
因为对象是在本类中创建的,所以需要提供一个方法让其它的类获取这个对象。
4、单例设计模式的写法
保证一个类的内存只存在一个对象
(1)、饿汉式
class Single {
private static Single instance=new Single();
private Single() {};
public static Single getInstance() {
return instance;
}
}
访问方式
Single instance = Single.getInstance();
(2)、懒汉式
class Single {
private static Single instance=null;
private Single() {};
public static synchronized Single getInstance() {
if(instance == null) {
instance = new Single();
}
return instance;
}
}
懒汉式用于实例的延迟加载,当多线程访问时会出现安全问题,可以用同步解决,加同步时用的锁是该类所属的字节码文件对象。