我的java学习之旅
第二周总结
在这一周我们学习了循环结构、函数、数组,并且经过前期粮草弹药的准备,再迈过了一道壕沟(循环)和两道护城河(函数、数组)之后,我们开始攻城了—>进入了java学习的核心部分,即面向对象的编程思想。接下来是一场硬仗!
循环结构
在循环结构部分,我们学习了for循环、while循环和do…while循环三种循环结构。
for循环
循环必须要满足三个必要条件:
1.初始值;
2.终点判定条件;
3.变化量;
for循环
for循环结构允许将三个必要条件都写在()内,用英文符的分号隔开,结构如下:
for(初始值;终点判定条件;变化量){
执行代码块;
}
while循环
while循环可以理解为是for循环的一个变体
while循环的()内只能写终点判定条件,具体结构如下:
初始值;
while(终点判定条件){
指定代码;
变化量;
}
while循环和for循环相比:
1.变量定义在循环外,生命周期变长了;
2.变化量放在循环内,要注意上下顺序可能对循环执行结果产生的影响;
do…while循环
do…while循环和while循环的结构类似,具体结构如下:
初始值;
do{
执行代码;
}while(终点判定条件);
do…while循环和while循环的区别:
1.while循环先判断后执行,条件不满足,不执行;
2.do…while循环先执行后判断,条件不满足,至少执行一次;
break和continue关键字
break和continue都是用来中断循环的,但是具体方式不同
break
break是用来中断循环的,即:当满足条件时,直接跳出循环,不再执行;
continue
continue是用来中断本次循环的,即:当满足条件时,中断本次循环,继续执行下一次循环;
注意
嵌套循环时,break和continue中断的是内层循环,如果想要中断外层循环,就需要给循环做标记。
函数
函数是实现特定功能的一段代码,可以反复使用。
函数的结构
权限修饰符 特征修饰符 [返回值类型] 函数名称 ([参数列表]){
函数主体;
[返回值;]
}
其中用[]包起来的,是可以有,也可以没有的
函数的调用
要想使用函数必须通过调用函数来实现。
注意:调用函数时,会优先执行函数内部的代码,结束之后,返回调用函数处,继续向下执行。
函数的分类
函数根据有无参数和返回值可以分为四类:
1.无参数无返回值;
2.无参数有返回值;
3.有参数无返回值;
4.有参数有返回值;
函数的参数
多数情况下,函数与调用者之间需要数据的交互,调用者必须提供必要的数据,才能使函数完成相应的功能,而在调用时,所传入的数据,被称为参数。
函数的参数可以没有,也可以有多个。
形参与实参
1.形参可以理解为方法执行时的临时变量空间;
2.实参可以理解为方法调用时传递进去的参数;
3.方法调用时会将实参的内容传递给形参;
4.如果实参的内容是基本类型,那么传递的是值,形参改变,实参不会改变;
5.如果实参的内容是引用类型,那么传递的是引用,形参改变,实参跟着改变;
函数的返回值
函数调用时,一些情况下无需返回结果;另一些情况下必须返回结果。
返回值可以理解为调用的方法执行完之后,留下的一个结果。
返回值类型:定义时,即约定了返回结果的类型。
return关键字
1.应用在有返回值的函数中,表示结束当前函数,并伴有返回值返回到调用函数处;
2.应用在没有返回值的函数中,表示结束当前函数,直接返回到调用函数处;
函数的多级调用
即在一个函数中调用另一个函数。
递归
递归就是在函数内部调用自己;
在实际开发中,递归可以解决具有既定规律的特定问题。
1.何时使用递归?
当需要解决的问题可以拆分成若干个小问题,大小问题的解决方法相同。
2,.如何正确使用递归?
需要设置有效地出口条件,避免无穷递归。
数组
数组是一组数据类型相同的数据的组合,讲这些数据统一管理起来。
数组是一个引用类型,数组内可以存储基本类型,也可以存储引用类型。
数组的定义(声明)
数据类型[] 数组名字;
数据类型 数组名字[];
数据类型 []数组名字;
注意:第二种和第三种写法是合法的,但是不推荐。
数组的赋值(初始化)
1.静态初始化
标准写法:
数据类型[] 数组名字 = new 数据类型[]{元素1,元素2,元素3,…};
简化写法:
数据类型[] 数组名字 = {元素1,元素2,元素3,…};
2.动态初始化
数据类型[] 数组名字 = new 数据类型[数组长度];
静态初始化和动态初始化比较:
1.静态初始化有长度也有元素;
2.动态初始化只有长度没有元素(不是真没有,是默认值);
补充:
1.整数类型的默认值:0
2.浮点型的默认值:0.0
3.布尔型的默认值:false
4.字符型的默认值:0对应的char值
5.引用类型的默认值:null
数组元素的访问
通过元素在数组中的位置(index索引)来访问元素,可以存值,可以取值。
索引是由取值范围的:[0~数组长度-1]
如果索引超出范围,会出现一个异常:ArrayIndexOutOfBoundsException---->数组元素越界
数组元素的遍历(轮询)
通过循环的方式访问数组中的每一个元素
for(int i=0;i<array.length;i++){
int value = array[i];
System.out.println(value);
}
在JDK1.5版本之后,出现了一个新特性,即:增强for循环(forEach)
for(int value:array){
System.out.println(value);
}
数组的特点
1.数组本身是一个引用类型;
2.数组是在堆内存中的一串连续的引用(地址)存在;
3.数组在初始化时必须制定长度;
4.堆内存中的数组长度一旦确定,就不能再次发生改变;
5.栈内存中的变量存储的是数组的地址引用;
6.数组内部存储的可以是基本类型,也可以是引用类型;
多维数组
当数组中存储的元素也是数组,那么这个数组成为二维数组,多维数组以此类推。
二维数组的定义(声明)
数组里面存储的数组类型[] 数组名字;
例如:int[][] array;
二维数组的初始化
1.静态初始化
数组里面存储的数组类型[] 数组名字 = {{元素1,元素2,},{元素1,元素2}};
例如:int[][] array = {{1,2},{3,4};
二维数组的访问
通过元素在数组中的位置来访问
array[i][j]
i控制大数组中小数组的位置
j控制小数组中元素的位置
二维数组的遍历(轮询)
用正常for循环或者加强for循环嵌套完成
面向对象的编程思想
类和对象
1.类是一个抽象笼统的概念,用来描述一类具有相同特征和行为的事物。
比如人类:
有名字 有年龄 有性别---->静态的特征(属性)
能吃饭 能说话 能学习---->动态的行为(方法)
2.对象是某个类中的某一个具体的个体
比如人类中有一个个体叫张三
用属性或者方法来描述类,然后在类中创建一个具体的对象,让对象去执行方法。
属性
静态描述类的特征
属性必要的组成部分:
1.修饰符
权限修饰符 [特征修饰符] 可以不写
2.数据类型
3.属性名字
public class Person{//用来描述人类的特征
String name;//也叫全局变量
//这里的name也可以赋值,但是不合理,因为erson这个类是描述人类特征的,不能所有的人都叫一个名字,但是属性是有默认值的
int age;
String sex;
//......
public static void main(String[] args){
//想要实现对属性的操作,必须先创建一个当前类的对象
Person p = new Person();//创建一个叫p的人(对象)
//通过对象. 的方式来调用属性
p.name = "张三";
p.age = 18;
p.sex = "男";
System.out.println(p.name+"今年"+p.age+"岁,性别:"+p.sex);
}
}
方法
方法的结构
权限修饰符 [特征修饰符] [返回值类型] 方法名字([参数列表]) [抛出异常][{方法体}]
其中用[]包起来的都不是必须得有的
方法的分类
方法根据有无参数和返回值可以分为四类:
1.无参数无返回值;
2.无参数有返回值;
3.有参数无返回值;
4.有参数有返回值;
注意:方法中如果设定返回值,那么必须有返回值,并且只能有一个。
第三周总结
面向对象(二)
构造方法
1.结构:
权限修饰符 方法名 ([参数列表]) [抛出异常] {
创建一个当前类的对象;
返回对象;
}
其中方法名必须与类名一致,[]包起来的表示不是必须有的
2.作用:
构建(构造)当前类的对象
3.用法:
通过new关键字来调用
new 方法名();
4.特点:
a.每一个类都有一个构造方法,如果在类中没有定义,系统会默认提供一个无参的构造方法;
b.构造方法可以重载;
this关键字
1.this是一个指代词,代替的是当前调用方法或属性,或者构造方法中创建的当前对象;
2.用法
this可以调用属性/方法;
this可以调用构造方法;
例如:this(); this(实参);
程序块(代码块)
块可以理解为一个非常特殊的无修饰符、无返回值、无参数、无名字的方法
1.结构:
{
执行代码;
}
3.用法:
每次在调用构造方法之前,系统会自动调用一次程序块;
4.特点:
无重载的概念,但是可以在类中定义多个块;
面向对象的三大特性
封装
1.概念:
尽可能隐藏对象的内部实现细节,控制对象的修改及访问权限。
2.作用:
a.保护数据或执行过程的安全;
b.增强代码的复用性;
3.访问:
get/set方法是外部访问对象私有属性的唯一通道,方法内部可以对数据进行检测和过滤。
继承
1.子类继承父类,通过一个关键字extends,子类就可以调用父类中的属性和方法,当做自己的来使用;
2.子类中也可以添加自己独有的属性和方法;
3.子类从父类中继承过来的方法不能满足子类需求的,也可以在子类中进行重写(覆盖)父类的方法;
4.方法重写与方法重载的区别:
区别 | 方法重写 (override) | 方法重载(overload) |
---|---|---|
类 | 具有继承关系的两个类 | 一个类中的一组方法 |
权限修饰符 | 子类可以大于等于父类 | 没有要求 |
特征修饰符 | 父类为final,子类不能重写;父类为static子类不存在;父类为abstract,子类必须重写; | 没有要求 |
返回值 | 子类可以小于等于父类 | 没有要求 |
名字 | 子类必须与父类一致 | 一个类中的多个方法名必须一致 |
参数列表 | 子类与父类一致 | 每个方法的参数必须不一致(个数、类型、顺序) |
异常 | 父类抛出运行时异常,子类可以不理会;父类抛出编译时异常,子类抛出异常的个数少于等于父类,子类抛出异常的类型小于等于父类 | 没有要求 |
方法体 | 子类与父类方法内容不一致 | 每一个重载的方法,执行过程不一致 |
5.每一个类都有一个继承类,如果不写extends关键字,则默认继承Object
Obiect是任何一个引用类型的父类(都直接或间接继承了Object)
Object是没有父类的
Object类中的九个方法:
toString() | 打印输出时,将一个对象转为字符串 |
hashcode() | 将对象在内存中的地址经过计算得到一个int整数 |
equals() | 用来比较两个对象的内容 |
getClass() | 获取对象对应类的类映射(反射) |
wait() | 让线程进入挂起等待状态(存在重载) |
notify() | 线程唤醒 |
notifyAll() | 唤醒所有 |
finalize() | 权限修饰符是protected,在对象被GC回收的时候,默认调用执行的方法 |
clone() | 权限修饰符是protected,是为了克隆对象 |
6.java中继承是单个存在的,每一个类都只能有一个继承类(在extends关键在后面只能有一个类存在);
但是可以通过传递的方式实现多继承的效果。
super关键字与this关键字
1.this和super都是指代词,代替的都是对象;
2.this指代的是当前执行方法或属性时的那个对象,不一定是当前类的对象;
3.super指代的是当前对象的父类对象;
4.this和super都能调用一般属性和一般方法;
5.this和super都可以放在类成员的任意位置(属性、方法、构造方法、块);
注意:在调用一般方法时,可以来回调用(可以编译),但在执行时可能会产生问题(StackOverflowError)
6.都可以调用构造方法,但是只能放在构造方法的第一行,并且不能来回调用;
7.this和super在构造方法中调用另一个类的构造方法时,不能同时出现在第一行。
多态
同一个对象,体现出来的多种不同的形态(身份),将一种行为表现出不同的效果。
想要实现多态,需要先有继承关系。
多态的体现
1.父类类型的引用,指向子类对象;
2.该引用只能调用父类中定义的属性或方法;
3.如果子类中将父类的方法重写,那么调用方法后的执行结果是子类重写之后的方法的结果;
4.如果需要调用子类独有的方法,需要先将类型还原成真实类型;
5.向下转型(造型)时,只能在有继承关系时造型,造型时可能会产生一个异常ClassCastException
应用场景
1.使用父类作为方法形参实现多态,使方法参数的类型更为宽泛;
2.使用父类作为方法返回值实现多态,使方法可以返回不同子类对象。
instanceof关键字
向下转型之前,可以先使用instanceof关键字判断引用中的对象真实类型, 保证类型转换的真实性。
造型
1.向上转型:
父类引用中保存真实子类对象,称为向上转型。
2.向下转型:
将父类引用中的真实子类对象,强转回子类本身类型,称为向下转型。
修饰符
abstract
- 用法:
1.可以修饰方法
用abstract修饰的方法,只有方法的结构,没有方法的执行体(即大括号),称为抽象方法。
2.可以修饰类
用abstract修饰的类,称为抽象类;
注意:
抽象类中不是必须含有抽象方法的;
抽象方法必须放在抽象类或接口中。 - 抽象类的特点:
1.属性:可以含有一般的属性,也可以含有private、static、final等修饰的;
2.方法:可以含有一般方法,也可以含有private、static、final等修饰的;
3.块:可以含有一般块,也可以含有静态块;
4.构造方法:可以含有构造方法,包括重载。 - 抽象类的使用
1.抽象类含有构造方法,但我们不能通过调用构造方法来直接创建对象;
2.抽象类只能通过子类继承来实现具体的操作。 - 关系
1.抽象类可以直接单继承抽象类;
2.抽象类可以直接单继承具体类(通常不这么做)
3.具体类不可以直接单继承抽象类,需要将父类的抽象方法具体化或者将自己也变成抽象类。