编程基础
基本语法
基本格式
1 | 修饰符 class 类名{ |
- 结构定义语句用于声明一个类或方法
- 功能执行语句用于实现具体得功能,且最后要用
;
结束
注意:
- JAVA严格区分大小写
- 一个连续得字符串不能分成两行书写,但可以分成两个字符串用
+
连接
例子
1 | package 包名; |
注释
1 | 单行注释: |
标识符
标识符可以由字母、数字、下画线_
和美元符号$
组成,但标识符不能以数字开头,不能是JAVA中得关键字。
规则:
- 包名的所有字母小写:cn.itcast.test
- 类名和接口名的每个单词首字母大写:ArrayList
- 常量名的所有字母大写,单词间下画线连接:DAY_OF_MONTH
- 变量名和方法名的第一个单词首字母小写,其他首字母大写:lineNumber
- 使用有意义的英文单词定义:password
关键字
- 关键字小写
- 关键字不命名标识符
- 保留关键字
const,goto
,无意义但不能作标识符 true,false,null
不属于关键字也不作为标识符
常量
- 整形常量
- 二进制(0b/0B开头)
- 八进制(0开头)
- 十进制
- 十六进制(0x/0X开头)
- 浮点数常量
- 单精度浮点数float (后缀-F/-f:2e3f)
- 双精度浮点数**double **(后缀-D/-d,不加后缀:3.6d)
- 字符常量
'
一个字符'
- Unicode字符集:’\u0000’空白字符
- 字符串常量
"
一串连续的字符"
- 布尔常量
- true 和 false
- null常量
- null,表示对象的引用为空
变量
数据类型
- 基本数据类型
- 数值型
- 整数类型
- 字节型 byte(1B)
- 短整型 short(2B)
- 整形 int(4B)
- 长整型 long(8B,后缀-L/-l)
- 浮点数类型
- float(4B,,后缀-F/-f)
- double(8B,后缀-D/-d,不加后缀)
- 整数类型
- 字符型 char
- 布尔型 boolean
- 数值型
- 引用数据类型
类型转换
-
自动类型转换/隐式类型转换
-
强制类型转换/显式类型转换
byte b = (byte)num;
作用域
以大括号包围的为范围
运算符
算术运算符
+3,-3,+,-,*,/.%(正负取决于左边的数),a++,++a,a--,--a
赋值运算符
=,+=,-=,*=,/=,%=
比较运算符
==,!=,<,>,<=,>=
逻辑运算符
&与,|或,^异或,!非,&&短路与,||短路或
优先级

结构语句
选择结构语句
-
if条件语句
1
2
3
4
5
6
7
8
9
10
11
12if(a >= 100)
{
b = 100;
}
else if(a < 100 && a >= 60)
{
b = 60;
}
else
{
b = 0;
} -
三元运算符
1
2a>=100?b=100:(a<100&&a>=60?b=60:b=0);
-> a>=100?b=100:a<100&&a>=60?b=60:b=0; -
switch条件语句
1
2
3
4
5
6
7
8
9
10
11switch(a){
case 100:
b = 100;
break;
case 60:
b = 60;
break;
default
b = 0;
break;
}
循环结构语句
-
while循环语句
1
2
3
4int x = 4;
while(x <= 4){
x--;
} -
do…while循环语句
1
2
3
4int x = 5;
do{
x--;
}while(x <= 4); -
for循环语句
1
2
3
4int x = 4;
for(int i=0; i<=4; i++){
x--;
} -
跳转语句
- break语句(直接结束当前循环)
- continue语句(跳过循环中的一次)
方法
语法格式
1 | 修饰符 返回值类型 方法名(参数类型 参数1, 参数类型 参数2, ...){ |
- 修饰符:static, final…
方法重载
相同的方法名,以不同参数区分不同方法
1 | package exp02; |
数组
一维数组
-
法一
1
2
3int[] x;
x = new int[100];//变量初始值默认都为0
x[0] = 11; -
法二
1
2int[] x = new int[5];
x[0] = 88; -
法三
1
2int[] x = {1,2,3,4,5};
int[] x = new int[5] {1,2,3,4,5};
arr = null
表示没有指向任何数组,通过该变量访问数组元素会出现空指针异常
arr.length
获得数组长度,即元素个数
二维数组
-
法一
1
int[][] x = new int[3][4
-
法二
1
2int[][] x = new int[3][];
x[0] = new int[] {1,2,3}; -
法三
1
int[][] x = {{1,2},{1,2,3},{1,2,3,4}};
排序
1 | package exp02; |
面向对象(上)
面向对象
面向对象和面向过程:
- 面向对象的思想:程序中使用对象映射现实中的事物,使用对象的关系描述事物之间的联系
- 面向过程的思想:通过分析得出解决问题所需的步骤,然后写出函数将步骤实现,使用时依次调用
面向对象的特性:
- 封装性
- 继承性
- 多态性
类与对象
类和对象是最基本、最重要的单元。类表示某类群体的一些基本特征的抽象,对象表示一个个具体的事物。
类用于描述多个对象的共同特征,它是对象的模板。对象用于描述现实中的个体,它是类的实例。对象是根据类创建的,一个类可以对应多个对象。比如车是一个类具有所有车的共性,出租车、卡车、货车是对象还具有特性。
类的定义
类是对象的抽象,用于描述一组对象的共同特征和行为。
类中可以定义成员变量和成员方法。成员变量,又称对象的属性,用于描述对象的特征。成员方法,简称方法,用于描述对象的行为。
1 | //定义Student类:class+类名 |
注意:类中的成员变量和成员方法中的局部变量可以同名,但方法中变量名访问的是局部变量而不是成员变量。
对象的创建与使用
要想要使用一个类,必须创建该类的对象。new关键字创建对象:
-
形式一
1
2
3
4
5
6//1.声明对象:类名 对象名 = null;
//声明一个Student类的变量stu(栈内存)
Student stu = null;
//2.实例化对象:对象名 = new 类名();
//运算符=将新创建的实例对象地址赋值给变量stu(堆内存)
stu = new Student(); -
形式二
1
Student stu = new Student();
注意:对象名stu保存在栈内存中,而对象属性信息保存在对应的堆内存中。new关键字创建的对象在堆内存中分配空间。
1 | 对象使用 |
对象的引用传递
类属于引用数据类型,引用数据类型的内存空间可以同时被多个栈内存引用。所谓的引用传递,就是将一个堆内存空间的使用权分配给多个栈内存空间使用,每个栈内存空间都可以修改堆内存空间的内容,即:多个变量被赋予了同一个实例对象地址(无数的小明……),一个变量把内容修改了所有变量都修改(一个小明剪了平头,所有其他小明同时变成平头)。
1 | Student stu = new Student(); |
注意:一个栈内存空间只能指向一个堆内存空间。如果想要再指向其他堆内存空间,就必须先断开已有的指向,才能分配新的指向。
4种访问控制权限
4种访问控制权限按级别由低到高:
- private:私有访问权限。修饰类的属性和方法,也可以修饰内部类。类的成员只能在本类中访问。
- default:默认访问权限。表现形式:类中属性或方法无任何访问权限声明。类的成员可以被本包中的其他类访问,但不能被其他包的类访问。
- protected:受保护的访问权限。类的成员只能被本包以及不同包的子类访问
- public:公共访问权限。类的成员可以在所有类中被访问,不限制包。
注意:外部类的访问权限只能是public和default。局部成员是没有访问控制权限。
封装性
封装是指将类的实现细节包装、隐藏起来的方法。
为了避免信息错误(age = -18),设计类时,应该对成员变量的访问做出一些限制,不允许外界随意访问,这就需要实现类的封装。
封装的具体实现过程:
- 定义一个类时,将类中的属性私有化(private关键字)
- 定义public修饰的公有方法来访问私有变量,包括获取属性值的getter方法和设置属性值得setter方法。
1 | package exp02; |
构造方法
如果需要在实例化对象时为这个对象的属性赋值,可以通过构造方法实现。构造方法,又称为构造器,是类的一个特殊成员方法,在类实例化对象时自动调用。
构造方法的定义
1 | class Student{ |
注意:
- 构造方法的名字要与类名一致
- 构造方法名前不能有任何返回值类型声明,也不能在构造方法中return值,但可以单return作为方法结束。
- 构造方法的调用在关键字new实例化对象的时候
- 有参构造方法可以实现方法重载(参数类型或个数不同)
- 每个类至少有一个构造方法。如果没有定义构造方法,系统会自动创建一个默认构造方法(无参无代码)。但类定义了构造方法,系统不会提供默认构造函数。
- 可以使用this在构造方法中调用其他构造方法(详见this关键字调用构造方法)
this关键字
调用本类中的属性
当成员变量和局部变量发生重名问题时,需要用this关键字分辨成员变量和局部变量。
1 | class Student{ |
调用成员方法
1 | class Student{ |
调用构造方法
构造方法在实例化对象时被JAVA虚拟机自动调用,在程序中不能像成员方法那样调用构造函数。但可以在一个构造方法中使用“this(…)”调用其他构造方法。
1 | class Student{ |
注意:
- 只能在构造方法中使用this调用其他的构造方法
- 在构造方法中,使用this调用其他的构造方法的语句必须位于第一行,且只能出现一次
- 不能在类中使用this互相调用
代码块
{}括起来的一段代码
普通代码块
一对{}就是一个代码块,main方法中定义了一个局部代码块,实现“分隔”,起到限定作用域的作用,互不影响。
1 | public class demo01{ |
构造块
直接在类中定义的代码块
1 | class Student{ |
结论:
- 构造块和构造方法同级,但实例化对象时,构造块比构造方法先执行
静态代码块
1 | class Student{ |
同步代码块
多线程部分讲解
static关键字
用于修饰类的成员,如成员变量、成员方法、代码块等。
如果一个方法与他所在类的实例对象无关,那么它就应该是静态的,而不应该把它写成实例方法。所以所有的实例方法都与实例有关,既然与实例有关,那么创建实例就是必然的步骤。
静态属性
静态属性,又称全局属性,可以使用类名直接访问。
1 | class Student{ |
1 | Student.school = "B大学"; |
注意:
- static关键字将school属性变为公共属性,只分配一块内存空间,为Student类所有对象共享。
- 某个对象进行school属性的修改,全部对象的school属性都被修改。
- static只能修饰成员变量,不能修饰局部变量
静态方法
实现不创建对象的情况下,通过类名直接调用方法。(正常情况下需要将类实例化才能调用成员方法)
1 | class Student{ |
1 | Student.setSchool("B大学"); |
注意:
- 静态方法只能访问静态成员。
- 非静态成员需要先创建对象才能访问,即对象创建后非静态成员才会分配内存。
- **this 关键字不能用于引用类的静态成员。**这是因为this 关键字指向类的当前对象 ,并且静态成员不需要调用任何对象。可以直接访问类的静态成员,而无需在Java中创建对象。
- 静态方法不需要通过它所属的类的任何实例就可以被调用,因此在静态方法中不能使用this关键字,也不能直接访问所属类的实例变量和实例方法,但是可以直接访问所属类的静态变量和静态方法(静态方法只能调用静态变量)。
静态代码块
1 | class Student{ |
注意:
- 当类被加载时,静态代码块就会执行。由于类只加载一次,所以静态代码块只执行一次(类第一次使用)。
- 执行顺序:静态代码块->构造代码块->构造方法
例子
面向对象(下)
继承
概念:
-
继承描述的是事物间的从属关系,通过继承可以使多种事物之间形成一种关系体系。
-
JAVA类的继承是指在一个现有类的基础上构建一个新的类。
-
声明一个类继承另一个类,使用extends关键字
1
2
3
4
5
6class 父类{
...
}
class 子类 extends 父类{
...
}
特点:
- 构建的新类叫子类,现有的类叫父类
- 子类自动继承父类的属性和方法,子类只能访问父类中用public和protected修饰的属性和方法
- 类只支持单继承,不允许多继承但允许多层继承,即:一个人只能有一个爸爸,但可以有好多辈祖宗,爸爸可以有好多娃子
注意:there is no default constructor available in …
-
这个错误是由于继承引起的,原因是子类里写了并且使用了无参的构造方法但是它的父类(祖先)中却至少有一个是没有无参构造方法的,就会出现这个问题。原因:
-
1.一个类如果显式的定义了带参构造函数,那么默认无参构造函数自动失效 。我们都知道一个类如果没有定义构造函数,那么会有一个默认的无参构造函数供你调用就是MyClass()。 但是如果你定义了一个带参构造函数,而没有显式的定义无参构造函数,那么无参构造函数就被隐藏了。
-
2.一个类只要有父类,那么在它实例化的时候,一定是从顶级的父类开始创建。对于Java来说要一直追述到Object 祖宗(Object)-> 曾爷爷 -> 爷爷 -> 父亲 -> me
这个思维很自然,没有祖宗,何来后代?祖宗的一些东西都没准备好,后代怎么继承去用?
-
-
也就是说当你用子类的无参构造函数创建子类对象时,会去先递归调用父类的无参构造方法,这时候如果某个类的父类没有无参构造方法就会出错啦~
-
要么就是父类使用了有参构造,要么让父类再写个无参构造,要么子类继续写有参构造。
继承的创建和使用
1 | //父类 |
1 | //子类 |
1 | //main函数 |
方法重写
-
子类中重写父类,即子类对父类继承的方法进行一些修改。
-
子类重写的方法需要和父类中被重写的方法具有相同的方法名、参数列表以及返回值类型。
1
2
3
4
5
6//父类
class Student{
public void mode(){
System.out.println("学生的就读方式");
}
}1
2
3
4
5
6//子类
class Pupil extends Student{
public void mode(){
System.out.println("学生的就读方式为:走读");
}
}1
2
3//main函数
Pupil p = new Pupil();
p.mode();
注意:重写时,不能使用比父类的方法更严格的访问权限
super关键字
-
子类中使用super关键字访问父类成员,例如:子类重写父类的方法后,子类对象将无法访问父类中被子类重写过的函数,使用super关键字可以访问父类成员
-
super关键字可以在子类中访问父类的非私有方法、非私有属性和构造方法。
1
2
3
4
5
6//父类
class Student{
public void mode(){
System.out.println("学生的就读方式为:");
}
}1
2
3
4
5
6
7//子类
class Pupil extends Student{
public void mode(){
super.mode();
System.out.println("走读");
}
}
**注意:**super关键字调用父类构造方法的代码必须位于子类构造方法的第一个行,并且只能出现一次,所以this和super不能同时出现
final关键字
- 当父类的成员不希望被子类重写时,可以在声明父类的成员时使用final关键字修饰。
- final关键字修饰类、属性、方法
注意:
- 修饰的类不能是子类,且不可以被继承和派生子类
- 修饰的方法不能被子类重写
- 修饰的变量是常量,只能在声明时被赋值一次且后续不可修改
- final声明变量,变量名称要求全部大写
- 变量使用public static final声明,为全局常量
1 | //修饰类 |
抽象类和接口
抽象类
定义一个类中,有些用于描述类的行为特征而定义出的成员方法,因为方法的实现方式无法确定,所以使用abstract关键字修饰的抽象方法来实现,抽象方法在定义时不需要实现方法体。
1 | //父类:抽象类 |
1 | class Undergraduate extends Student{ |
注意:
- 抽象方法和类必须使用Abstract关键字修饰,包含抽象方法的类必须是抽象类(不能直接创建对象,可以使用匿名内部类完成抽象方法重写)
- 抽象方法在抽象类中定义时不需要实现方法体,抽象方法不能使用private关键词修饰
- 非抽象类继承抽象类后必须重写全部抽象方法。
接口
接口是抽象类衍生的一个概念(面向接口编程:将程序的不同的业务逻辑分离,以接口的形式对接不同的业务模块。接口中不实现任何业务逻辑,业务逻辑实现和修改由接口的实现类完成。)。
接口是一种用来定义程序的协议,它用于描述类或结构的一组相关行为。使用接口的目的是克服单继承的限制,因为一个类只有一个父类,而一个类可以同时实现多个父接口。接口由全局常量、抽象方法、默认方法、静态方法组成,都是默认public访问权限(可省略)。
-
接口声明(interface关键字)
1
2
3
4
5
6[public] interface 接口名 [extends 接口1,接口2,...]{
[public static final] double Pi = 3.1415926;
[public abstract] double area(double x);
[public] static 返回值数据类型 方法名(参数列表){}
[public] default 返回值数据类型 方法名(参数列表){}
} -
接口实现类定义(implements关键字)
1
2
3
4
5
6修饰符 class 类名 [extends 父类名] implements 接口1,接口2,...{
public double area(double x) {
return x*x;
}
...
}
注意:
- 接口是抽象类衍生的概念。使用接口的目的是克服单继承限制,一个类可以实现多个父接口。
- 接口不能实例化,通过接口实现类的实例化对象进行方法调用。接口的访问权限都为public(可省略),可以定义全局变量(public static final)、抽象类(public abstract)、默认方法(public default)、静态方法(public static)。
- 接口可以继承多个接口,但不能继承抽象类。
例子
设计一个Shape接口和它的两个实现类Square和Circle。要求如下:
① Shape接口中有一个抽象方法area(),方法接收有一个double类型的参数,返回一个double类型的结果。
② Square和Circle中实现了Shape接口的area()抽象方法,分别求正方形和圆形的面积并返回。
③ 在测试类中创建Square和Circle对象,计算边长为2的正方形面积和半径为3的圆形面积。
1 | interface Shape{ |
多态
多态是指不同类的对象在调用同一个方法时表现出的多种不同行为(重写)或在同一方法中由于参数类型/个数不同而导致执行效果不同的现象(重载),即实现同一方法名调用出不同行为。多态的两种形式:
- 方法的重载
- 对象的多态(方法的重写)
对象类型的转换
使用对象类型转换解决继承中的多态问题。
-
向上转型:子类对象 父类对象
父类对象想调用子类重写的父类方法为对象向上转型,但父类不能调用子类中定义的方法。向上转型,程序会自动完成。该方式可以实现新增子类,从而在子类中对父类的功能进行扩展,而不用修改父类的代码,保证程序的安全性。
1
Animal an1 = new Cat("阳阳",2);
-
向下转型:父类对象 子类对象
向下转型一般用于向上转型后想调用子类定义的方法。对象进行向下转型前必须先进行向上转型,否则异常。
1
2Animal an2 = new Dog("土豆",3);
Dog dog = (Dog) an2;
例子
参照、优化教材P130 Exmaple14要求如下:
① Animal有两个私有属性name(String),age(int)。
② Cat继承Animal类有一个方法action(),输出“猫捉老鼠”。
Dog继承Animal类有一个方法eat(),输出“狗啃骨头”。
③ 编写测试类,实现功能:当是Cat对象时输出基本信息加“喵喵”及“猫捉老鼠”;当是Dog对象时输出基本信息加“汪汪”及“狗啃骨头”
1 | package package01; |
Object类
Object类常用方法
内部类
四种内部类的特点
关键字总结
关键字 | 含义 | 备注 |
---|---|---|
class关键字 | 定义一个类 | class 类名{} |
new关键字 | 创建一个对象 | 类名 对象名=new 类名(); |
private关键字 | 私有访问权限,类内访问 | |
default关键字 | 默认访问权限,包内访问 | |
protected关键字 | 受保护访问权限,本包和不同包的子类访问 | |
public关键字 | 公共访问权限,全局范围 | |
this关键字 | 成员变量和局部变量发生重名问题 一个构造方法中使用“this(…)”调用其他构造方法 |
调用语句必须位于第一行,且只能出现一次 不能在类中使用this互相调用 |
static关键字 | 静态属性,又称全局属性,可以使用类名直接访问 实现不创建对象的情况下,通过类名直接调用方法 |
静态方法只能访问静态成员 this 关键字不能用于引用类的静态成员 静态代码块只执行一次,首先执行 |
extends关键字 | 声明一个类继承另一个类 | |
super关键字 | 子类访问父类成员 | 父类的非私有方法、非私有属性和构造方法 |
final关键字 | 不被子类重写 | 变量使用public static final声明,为全局常量 |
abstract关键字 | 抽象类和抽象方法 | |
interface关键字 | 接口声明 | |
implements关键字 | 接口实现类的定义 |