引言
接着上一次的继续学习,在上一次的学习中我们已经对Java有了些许的认识,也应该了解到了一些Java的
语法和底层知识。
现在,我们来接着上一次的内容继续学习,要是有看不懂的地方,请回顾上一次的知识总结。
for循环
循环三要素:变量初始化、循环条件、变量更新。
最为重要的一点就是控制好变量的更新,如果没有控制好,就会让你程序的执行达不到你的预期,且有可
能出现死循环的状况。
语法结构:
For( 【初始变量】; 【表达式】 ; 【变量更新】){
Java代码
}
执行步骤:
1、最先执行初始化步骤,For语句中可以定义多个变量,但是必须是同一个类型的,定义了int的之后,只能
再定义int型的了。
2、检测布尔表达式的值,如果为true,循环体呗执行。如果为false,循环终止,开始执行循环后面的语句。
3、执行完一次循环过后,要对循环控制变量的值进行更新,防止出现死循环的情况。
4、再次检测布尔表达式,循环上面三个步骤,直至循环中的布尔表达式值为false时,结束循环。
示例代码:
public class Test12 {
public static void main(String args[]) {
for(int x = 10; x < 20; x = x+1) {
System.out.print("value of x : " + x );
System.out.print("\n");
}
}
}
输出结果:
value of x : 10
value of x : 11
value of x : 12
value of x : 13
value of x : 14
value of x : 15
value of x : 16
value of x : 17
value of x : 18
value of x : 19
这是普通的单层for循环,利用for循环的好处就是,可以提高代码的重用性、减少代码量,能够让程序员很清
楚的看到当前程序的执行情况(例如输出i的值,就可以知道当前执行了几次程序)。
增强for循环
增强for循环又称为“foreach”。
一般用于数组的输出遍历,使用增强for循环可以减少程序员的负担。
语法结构:
for(声明语句 : 表达式){
//代码句子
}
注意:声明一个局部变量,该变量的数据类型必须和数组元素的类型一致,改变量来接受每一次数组中元
素,代码较为简洁。
示例代码:
public class Test13 {
public static void main(String args[]){
int [] numbers = {10, 20, 30, 40, 50};
for(int x : numbers ){
System.out.print( x );
System.out.print(",");
}
System.out.print("\n");
String [] names ={"James", "Larry", "Tom", "Lacy"};
for( String name : names ) {
System.out.print( name );
System.out.print(",");
}
}
}
输出结果:
10,20,30,40,50,James,Larry,Tom,Lacy,
for循环的嵌套
需要注意的是:外层循环控制行,内层循环控制列。外层循环循环一次。内层循环循环一遍。
语句格式:就是在普通for循环的循环体里面又写了一个普通for循环。
示例代码:
public static void main(String[] args) {
//外层循环 当条件满足的时候 循环一次
for(int i=0;i<2;i++) {
System.out.println("第"+i+"次开始报数");
//循环学生进行报数1--13 进行条件判断 1--13
for(int j=1;j<14;) {
System.out.println("第"+j+"报数");
if(j==10) {
continue;
}
j++;
}
//当内层循环一遍结束之 继续进行外层循环的判断
}
}
跳出语句
Break continue return 关键字
注意:都必须放再当前代码块的最后一行。
1、Break 结束当前循环
示例代码:
//输出1--10之间的所有数字,不输出7 之后的值
for(int i=1;i<=3;i++) {
System.out.print(i+"\t");
if(i==2) {
break;
}
System.out.print("我是break");
}
Break的加强版
定点跳出原来break只能结束当前所在循环,使用定点break,相当于给我们break添加一个跳出去的节点。
示例代码:
for(int i=1;i<3;i++) {
System.out.println("第"+i);
jieshu:
for(int j=1;j<=3;j++) {
System.out.println("我是第j"+j);
for(int k=1;k<4;k++) {
if(k==3) {
break jieshu;
}
System.out.println("我是k"+k);
}
}
}
2、Continue 结束本次循环 进入下一次循环
示例代码:
//输出1--10之间的所有数字,continue
for(int i=1;i<=3;i++) {
System.out.print(i+"\t");
if(i==2) {
continue;
}
System.out.print("我是continue");
}
3、Return 结束当前循环
示例代码 :
for(int i=1;i<=3;i++) {
System.out.print(i+"\t");
if(i==2) {
return;
}
System.out.print("我是return");
}
数组
可以理解为一个有层次的规则,每一层放的对象都可以一样,也可以不一样。
好处:你需要哪一层的对象可以直接取这一层的对象,不需要将所有的对象都拿出来。
数组的使用规则:
1.既能存储原始数据类型,又能存储对象类型。
2.数组元素的个数称为数组的长度。长度一旦确定,就不能改变。
3.数组元素的下标是从0开始的,即第一个元素的下标是0。
4.可以创建数组的数组。
5.数组可以作为对象处理。数组对象含有成员变量length,用来表示数组的长度。
规则说明有以下几点:
1.可以只给部分元素赋初值。
2.只能给元素逐个赋值,不能给数组整体赋值。
3.如不给可初始化的数组赋初值,则全部元素均为0值。(基本数据类型)
4.如给全部元素赋值,则在数组说明中, 可以不给出数组元素的个数。
根据使用规则来进行数组的创建:
1、创建的语法
数组类型 [] 数组的名字; (推荐使用)
数组类型 数组的名字[];
2、数组的赋值方式
①先声明,后赋值。
在创建的时候只给定长度,不给具体的值。
num=new int[5];
②直接赋值
在创建的时候给具体的值,不明确长度。
num=new int[]{1,5,8,25};
数组的使用
数组中的所有的值称为数组的元素,数组的元素个数称为数组的长度。数组的长度是数组.length,数组中的
每一个元素都有一个下标,下标从0开始,数组下标的最大值是数组的长度减1。
查看数组的长度:
num.length。//数组的长度结果是int类型的。
int leng=num.length; //使用变量来接收数组的长度
System.out.println(num2.length); //直接输出长度
数组的赋值:根据数组的元素下标。
num1[0]=10;
num1[2]=20;
查看数组的元素 :根据数组的元素下标
①一个一个的查看
在去使用元素下标获取数组中的元素值的时候,可以使用数组.length进行计算。用来接收数组元素的变量的
数据类型必须数组的类型一致。
//查看数组的值
int temp=num1[0];
int temp1=num2[3];
System.out.println(temp);
System.out.println(temp1);
System.out.println(num1[num1.length-2]);
②使用循环查看数组中的所有的元素
for(int i=0;i<num2.length;i++) {
System.out.println(num2[i]);
}
注意:在使用for循环的时候,一定要避免是数组的元素下标越界(就是循环中i的值超出了数组元素的个
数)。
③增强for循环的使用
//使用for each 循环
for(int temp:num2) {
System.out.println(temp);
}
好处:不需要自己考虑数组的长度,但是临时变量的数据类型必须与数组的类型保持一致。除非是数组的大
类型。
多维数组
多维数组就是一维数组中的元素是数组。
示例代码:
public static void main(String[] args) {
//创建两个数组
int [] num1=new int[3];
int [] num2=new int[] {1,5,68,54,30,60};
//创建多维数组
int [][] num3=new int[2][];
num3[0]=num1;
num3[1]=num2;
for(int i=0;i<=num3.length-1;i++) {
for(int j=0;j<num3[i].length;j++) {
System.out.println(num3[i][j]);
}
}
}
数组的排序
①选择排序
思想:在进行比较时,假设当前数组第一个元素为最值,用该元素和其余元素挨个比较,根据比较情况决定
是否进行交换,每一次比较都是在前一次确定数组元素下标的下一个元素开始,且每一次比较进行的循环次
数都是比前一次循环次数少1
示例代码:
public static void main(String[] args) {
//选择排序的特点,假设第一个位置的值最小或最大,与剩下的所有值挨个对比,每一次循环结束,
//确定了第一个元素位置的值为最大或最小
int[] num=new int[] {10,69,87,54,19,256,41};
int temp;
for(int i=0;i<num.length;i++) {
for(int j=i+1;j<num.length;j++) {
if(num[i]>num[j]) {
temp=num[i];
num[i]=num[j];
num[j]=temp;
}
}
}
for(int i=0;i<num.length;i++) {
System.out.print(" 第"+i+"个元素:"+num[i]);
}
}
}
②冒泡排序
思想:两两比较,每一次循环完都确认了最后一个数组元素的值为最大或者最小,且每一次循环都比前一次
循环少一次。每一次循环比较都是从下标0开始的。
public class MaoPao {
public static void main(String[] args) {
// TODO Auto-generated method stub
int [] array=new int[]{3,5,1,8,6};
int temp;
//外层循环控制的是比较次数
for(int i=0;i<array.length;i++){
//获取元素下标进行元素的比较
//内层循环循环一遍就可以获得当前的最大值
//每一次的比较后,下一次比较就是取最大值之外的数
//array.length-i-1 : 下一次比较次数是数组最大长度-1-比较的次数
for(int j=0;j<array.length-i-1;j++){
if(array[j]>array[j+1]){
temp=array[j];
array[j]=array[j+1];
array[j+1]=temp;
}
}
}
System.out.println("由小到大依次排序为:");
for(int temp1:array){
System.out.print(temp1+" ");
}
}
}
面向对象
此前,我们学习了Java中的基础,现在,我们才步入了Java语言的核心,众所周知,Java语言的一大特色就
是面向对象。那么,什么是对象,什么又是面向对象呢?
OOP面向对象编程
面向过程是以函数为基础,完成各种操作,强调过程;面向过程的编程语言,强调的是功能行为,注重过程
的一步步实现。而面向对象是以对象为基础,完成各种操作主要强调对象、结果。
面向对象里面的基础就是类和对象。如果让我回答先有鸡还是先有蛋,我可能回答不上,但是你要是问我先
有类还是先有对象,那么我的回答是:先有类后有对象。具体原因请往下看。
一句普通的话:“谁是个什么”,谁就是对象,什么就是类。所以,程序是源于生活的。
什么对象?
所谓对象就是真实世界中的实体,对象与实体是一一对应的,也就是说现实世界中每一个实体都是一个对
象,它是一种具体的概念。
类是具备某些共同特征的实体的集合,它是一种抽象的概念,用程序设计的语言来说,类是一种抽象的数据
类型,它是对所具有相同特征实体的抽象。
类与对象的关系:
类是对象的集合,对象是类的实例;
对象是通过new classname产生的,用来调用类的方法;类的构造方法 .。
用一个例子给你说明一下他们的关系:
比如“人类”就是一个类,那么具体的某个人“张三”就是“人类”这个类的对象,而“名字、年龄”等信息就是对象
的属性,人的动作比如“吃饭、穿衣”等就是对象的方法。总之类就是有相同特征的事物的集合,而对象就是
类的一个具体实例。同时类有多态和继承,例如“人类”可以分为“男人、女人”,“老人、小孩”那么“男人、女
人”就是“人类”的子类等等。一楼的说“轿车”是一个实例化,我觉得有点不妥,“轿车”应该是“车”的一个子类,
例如“车牌号是***的轿车”才是一个对象。方法是被对象调用的比如“张三.穿衣()”,用static修饰的方法是静
态的方法或称为共享方法,一般用类名直接调用。
类:是具有相同属性和方法的多个对象的抽象。
属性是什么?
静态部分(描述) 变量
方法是什么?
动态部分(行为) 方法
对象:对象是通过new类得到,对象是具有自身属性和方法的类的一个具体的实例。
对象咋来的?
对象是通过new classname产生的,用来调用类的方法;类的构造方法 .。
类是创建对象的模板。
类是对象的抽象,对象是类的实例。
类也是一个对象。
类里面可以写什么?
类里面可以写java代码。
如何创建一个类:
Class 类名{ } 类名必须符合命名规则
在同一个java文件中可以创建多个不同类名的类,但是只能有一个用public修饰的。用public修饰的类名必须
与java文件的名字一致。
示例:
创建一个学生类:
class Student{
}
属性 用来描述对象或者类的静态部分
属性就是变量 数据类型 变量
数据类型可以是基本数据类型,也可以是引用数据类型类(类类型)
创建属性(可以赋值也可以不赋值):
//属性部分
class Student{
String name;
int age;
String sex="男";
int sid;
}
同过类来创建一个学生对象:(创建对象,是在堆内存中创建了新空间)
class Student{
String name;
int age;
String sex="男";
int sid;
}
public class Test{
public static void main(String[] args){
Student stu=new Student();
}
}
调用对象的属性 对象名.属性名:
class Student{
String name;
int age;
String sex="男";
int sid;
}
public class Test{
public static void main(String[] args){
Student stu=new Student();
stu.name="张三";
stu.age=15;
stu.sid=123;
stu.sex="女";
System.out.println(stu.name+stu.age+stu.sex+stu.sid);
}
}
构造方法
就是用来创建对象的时候用的。
语法: public 类名(【参数】){
java代码
}(只能使用public修饰)
参数怎么写:变量 变量的类型 名字
有参数构造方法 是在new对象给对象赋值,给对象的属性赋值。
如果类中没有属性就不能创建有参数构造方法,参数的个数可以是多个。不要超过属性的个数。 参数的名
字可以与你要赋值的属性的名字一致,如果一致的话必须使用this关键字来进行参数和属性的区分。如果不
用this就必须将参数的名字和属性的名不一样,但是参数的类型必须与要赋值的属性一致。
无参数构造方法 创建对象的时候不赋值
public 类名(【无参数】){
java代码
}
当类中没有任何构造方法的时候,会有一个默认的无参数构造方法,但是一旦类中有了有参数构造方
法,就不会再有默认无参数构造方法。如果你在类中写了有参数构造方法,就一定要把无参数构造方法也显
示的写出来。
构造方法的调用
在创建对象的时候根据有没有传参数来调用
new Person(); 根据你空号中是否传值,不传值代表调用的是无参数构造方法,
如果传参数:根据参数的个数调用对应有参数构造方法,实际传的参数的类型必须与你要使用的有参数构造
方法的参数类型以及类型的顺序一致。
属性分为全局属性和局部属性:
全局属性归当前类所有,他会有默认值,可以被当前所有非静态static方法调用。
局部属性归当前区域(方法)所有,局部变量在使用之前必须进行赋值,没有默认值。
当局部变量与全局变量名字相同时,采取局部优先原则。
静态属性可以被非静态方法和静态方法直接调用。非静态属性只能被非静态方法直接调用。
Static 静态修饰符
被static修饰的属性和方法都属于类所有。在使用属性或者方法的时候可以直接是类名.方法名进行调用。
代码块
{
代码块
}
代码块属于类所有,随着对象的创建被调用。每一次创建对象的时候都会被调用一次。
静态代码块
Static{
静态代码块
}
static{
System.out.println("我是静态代码块");
}
在程序启动类被加载到内存中的时候就会被调用,并且只调用一次。
静态修饰符的使用:
可以使用static进行属性和方法的修饰。
修饰属性:satic 数据类型 属性名; 静态属性 全局属性
非静态属性只能被非静态方法直接调用,静态属性可以被静态或非静态方法直接调用。
静态属性属于类的,非静态属性属于对象的。
修饰方法:Public static 返回值类型 方法名(【参数】){}
静态方法归类所有, 类名.方法名(【参数】);
非静态方法归对象所有。对象名.方法名(【参数】);
静态方法也可以被对象进行调用
代码示例:
public class StaticShuXingDemo {
//静态属性
static String name;
int age;
static {
// name="张三";
StaticShuXingDemo ssd= new StaticShuXingDemo();
ssd.age=10;
ssd.name="李四";
System.out.println("静态代码块被调用");
}
//非静态方法
public void getName() {
System.out.println(name);//静态属性可以被静态和非静态方法直接调用
System.out.println(age);
}
public static int getAge() {
// System.out.println(age);//报错 静态不能调用非静态属性
System.out.println(name);
return 15;
}
public static void main(String[] args) {
//调用静态方法
StaticShuXingDemo.getAge();
StaticShuXingDemo.getName();
StaticShuXingDemo ssd=new StaticShuXingDemo();
ssd.getName();
String str="ascfdvfbgbdf";
String str1=new String(str);
System.out.println(str1.toUpperCase());
}
方法的调用
如果方法是非静态的,那么需要是用new 对象
对象名.方法名(【参数】);
如果是静态方法,直接使用类名.方法名
类名.方法名(【参数】);
String类是一个特例:可以不用new对象就可以直接调用它自己的非静态方法。是因为它有一个叫做
字符串池的空间。
对象的引用
一个类可以引用另外一个类。将另外一个类当做自己的属性进行引用。
A类
public class AClass {
//A对象引用B对象 作为自己的属性
BClass bc;
public void study() {
bc=new BClass();
//调用B对象的study
bc.study();
}
}
B类
public class BClass {
//B对象引用C对象 作为自己的属性
CClass cc;
public void study() {
cc=new CClass("王五");
//调用C对象的study 传入c对象的name值
cc.study(cc.name);
}
}
C类
public class CClass {
String name;
public CClass(String name) {
this.name = name;
}
public void study(String name) {
System.out.println(name+"在学习");
}
}
测试类
public class Test {
public static void main(String[] args) {
//实例化对象 创建对象
AClass ac=new AClass();
ac.study();
}
}
面向对象的四大特性
抽象、封装、继承、多态。
抽象:
可借鉴于类和对象的定义。
封装:
封装就是使用方法来进行对属性的操作。
对私有化的属性进行封装。
一般封装的方法都称为get()和set()赋值,每一个私有属性都对应的有一个get和一个set方法,方法的
名是get或者set加上属性名字的首字母大写。例如: getName setName。
获取属性:(get+属性名(属性名首字母大写)返回值类型和对应属性数据类型相同)。
public int getAge() {
return age;
}
给属性赋值:(set+属性名(属性名首字母大写)参数类型和对应属性的数据类型一致)。
public void setAge(int age ) {
this.age=age;
}
继承:
两个类拥有关系,使用extends关键。
Public class aa extends bb{}
AA与BB是子父类关系。Aa是子类 BB是父类。
object超类,是所有Java类的父类。
特点:
①只能是单继承,一个类只能有一个直接父类。
②一个类可以有多个子类 父类必须有一个默认的无参构造方法。
③子类继承了父类就拥有了父类所有的属性和方法,(除去私有属性和方法)。
④可以在子类中写一个和父类一样的方法,方法的重写:在两个类中(子类和父类),方法的名字和参数以
及参数的类型、顺序、个数都一样。方法的返回值也必须一致。
⑤构造方法不能被继承。
关键字:this、super。
this代表当前对象
在使用方法的时候,一个类同时new出来多个实例对象,不同对象调用方法的时候,this代表不同的对象。
super出现在继承了父类的子类中。
有三种存在方式:
第一种
super.xxx;(xxx为变量名或对象名)
这种方法意义为,获取父类中的名字为xxx的变量或方法引用。
使用这种方法可以直接访问父类中的变量或对象,进行修改赋值等操作
第二种
super.xxx();(xxx为方法名)
这种方法意义为,直接访问并调用父类中的方法。
第三种
super();
这种方法意义为,调用父类的初始化方法,其实就是调用父类中的public xxx()方法;
多态
同一个对象拥有多种状态。
向上转型 子类转父类 Car cx = new JiaoCar();
编译时状态: 子类=子类
运行时状态: 子类=父类 将子类独有属性和方法进行隐藏
子类转父类----父类new子类,不需要强转 父类引用指向子类对象,当父类引用指向子类对象的时候,这个引
用对象只能调用父类和子类相同的子类方法,不能调用子类特有而父类没有的方法和属性。
向下转型 父类转子类 JiaoCar jc = (JiaoCar)cx;
必须是进行向上转型之后的那个父类对象,进行强制转换赋值给子类对象。 转型之后就可以调用子类独有
的属性和方法。
多态的体现:
方法的重写和重载。
instanceOf关键字是判断两个类是不是子父类关系。
将向上转型时候得到的对象与父类对象进行比较,看看是否是同类型的对象。
boolean bool = cx instanceof Car;
关键字前面是对象,后面是类。
返回一个布尔值,需要一个boolean变量来接受。
abstract抽象
抽象方法:例如:public abstract void aa();
只是在类中声明了行为,并没有具体的实现行为的代码。
抽象方法只能放在抽象类中,一个类中,只要有一个抽象方法,那么这个类必须被定义为抽象类。重写抽象
方法必须有具体的实现(有方法体)
抽象类:只是用来派生子类用的。
访问限定符 abstract class 类名{
属性
方法:
普通方法 访问限定符 返回值类型 名字(【参数】){}
抽象方法 访问限定符 abstract 返回值类型 名字(【参数】);
}
只能被继承,不能具体实例化,就是不能去new对象,只用来派生子类,子类必须实现(重写)所
有的抽象方法。(子类必须是非抽象类)。一个抽象类中可以有一个抽象方法,也可以没有抽象方法。
特点:
①所谓抽象方法,是指在类中仅仅声明了类的行为,并没有真正实现行为的代码。
② 类中只要有抽象方法,那么这个类必须被声明为抽象类。
③构造方法、静态(static)方法、最终(final)方法和私有(private)方法不能被声明为抽象的方法。构造
方法不能是抽象的,抽象方法不能是私有的。
④一个抽象类中可以有一个或多个抽象方法,也可以没有抽象方法。
⑤抽象类只能被继承(派生子类)而不能创建具体对象即不能被实例化。抽象类不能自己实例化自己。
⑥一个类如果继承了抽象类,那么就必须重写抽象中的所有抽象方法。重写抽象方法有具体的实现
Public abstract void getAll();抽象方法
Public void getAll(){};重写的方法
包的介绍和访问限定符
使用import语句导入类,在前边的程序中,我们已经使用过,其应用的一般格式如下:
import 包名.*; //可以使用包中所有的类。
import 包名.类名; //只装入包中类名指定的类。
在程序中直接引用类包中所需要的类。其引用的一般格式是:
包名.类名
例如,可以使用如下语句在程序中直接创建一个日期对象:
java.util.Date date1 = new java.util.Date( );-----需要了解但不推荐使用
访问限定符:
默认访问限定
public访问限定 公共的
private(私有的)访问限定
protected(保护的)访问限定 保护的就是自己在其他类中不能被直接调用。 可以被继承但是不能被直接调
用。
示意图:
下期待续~