Stage01 Day01
一、DOS命令行:
第一种方式:Win + R,然后输入cmd,最后按回车。
第二种方式:在地址栏中输入cmd,然后按回车,则打开当前目录所在的DOS命令窗口
dir : 列出当前目录下的文件以及文件夹
mkdir:创建文件夹
md : 创建目录
rd : 删除目录
rd\s\q :删除层级目录-
cd : 进入指定目录
cd.. : 退回到上一级目录
cd\: 退回到根目录
del : 删除文件
exit : 退出 dos 命令行
补充 :echo javase>1.doc 新建文件
dos常用快捷键
← →:移动光标
↑ ↓:调阅历史操作命令
Delete和Backspace:删除字符
二、Java语言的特性和优势
简单性
面向对象
可移植性(跨平台性)
高性能
分布式
动态性
安全性
健壮性:异常处理机制
Java的两种核心机制
Java虚拟机(jvm)
垃圾回收机制
三、Java 关键字和标识符
1.Java中具有一定特殊含义,并且全部小写的被称为关键字
2.Java中凡是可以自己起名字的地方,都称之为标识符。
3.标志符命名规则:
由26个英文字母大小写,0-9 ,_或 $ 组成
数字不可以开头。
不可以使用关键字和保留字,但能包含关键字和保留字。
Java中严格区分大小写,长度无限制。
标识符不能包含空格。
4.命名建议
1.标识符要见名知意,也就是:编写单词
比如:phone age year email
2.建议:类名每个单词首字母大写
比如:Hello Homework Student
3.建议:长度不要超过15个字符
比如:HelloWorld arguments----- >args
4.建议:变量名、方法名、参数名等采用驼峰命名法
比如:name firstName print getAge
四、Java中的变量
- 在Java中,利用声明的方式将某个数据保存下来供程序使用,并且这个数据是可以根据自己需求发生改变的。
2、基本数据类型
在内存中存放的是真正的值 值传递
引用数据类型
在内存中存放的是地址(引用) 址传递
五、数据类型
1.为什么要有数据类型的存在?
因为Java中的数据是有明确的类型划分的,为了确保变量保留的数据其类型的唯一性,要使用数据类型进行变量的修饰。
2.常用的数据类型
五、三目运算符
三目运算符也叫做条件运算符,用于完成条件判断的。
三目运算符的执行流程:先判断条件,如果条件为true,则执行?后的结果1,否则执行:后面的结果2。
当使用多选一时,则就使用三目嵌套完成
六、键盘接收用户输入的操作步骤
第一步:导入包,必须位于当前Java源文件所有类的最前面
import java.util.Scanner;
还可以编写为import java.util.*;
注意:在一个Java源文件中只需要编写一次导入包
第二步:创建Scanner对象
Scanner input = new Scanner(System.in);
注意:一个方法中只需要编写一次创建Scanner对象
第三步:友好提示(可有可无,但是建议编写上)
System.out.print("请输入:");
第四步:接收键盘输入
int a = input.nextInt(); //注意:当按回车键,则表示键盘输入完毕,并且将输入的值赋给左侧的变量名称a
double d = input.nextDouble();
String a = input.next(); //注意:在Java中,键盘接收字符串类型时,没有nextString(),而是编写为next()
Stage01 Day02
一、什么是程序流程控制结构
依据需求的不同会产生不同的程序结构,从而导致程序的执行流程也是不同的。我们把这一现象称之为程序的流程控制结构。
主要分为 顺序结构、选择结构、循环结构
二、顺序结构:
在程序的执行过程中,按照程序语句自上而下逐行执行程序的现象。是最简单的程序流程控制结构。
三、选择结构:
在程序的执行过程中先去判断条件是否成立,再根据条件的成立与否决定去执行对应的代码。
(1)if单选择结构:
if双选择结构:
if多选择结构:
(2)swich选择结构——主要用来等值匹配
四、循环结构
(1)什么是循环结构
在Java中,按照一定次数重复地去执行程序,直至达到次数上限,将重复的代码只编写一次,然后再重复执行即可,这样的程序结构就是循环结构。
(2)for循环
初始化 完成变量的初始值,比如:int i = 1;
布尔表达式 完成循环条件判断,如果条件为true,则执行循环,否则结束当前整个for循环
循环体 也就是:将重复的代码编写在循环体中,并且重复的代码只编写一次。
更新: 完成变量值的更改
(3)while循环结构
(4)do while循环结构
(5)双重循环结构
主要是for循环,外层循环控制行数,内层循环控制列数。
Stage01 Day03
一、方法的理解
方法就是对重复执行的代码片段处理的行为方式,它可以对重复执行地代码片段进行封装,并可做到随时任意使用,提升程序开发效率。
break关键字的使用:
break在哪使用
在switch case中使用,还可以在循环中使用
break作用:
当遇到break,则结束当前整个switch case或者结束当前整个循环,执行外面的语句。
continue关键字的使用:
continue在哪使用
只能在循环中使用
continue作用:
当遇到continue,则结束当前这一次循环,继续执行下一次循环.
return关键字的使用:
return在哪使用
在方法中使用
return作用:
当遇到return,则结束当前这个方法的执行,返回到方法的调用处
return特殊情况:
当方法是无返回值类型时,则可以在方法体中使用return,但是必须编写为return;
二 、方法的重载
1、概念
在一个类中允许同时存在两个或者两个以上拥有相同名字的方法,且参数列表不同,与返回值类型无关,这样的方法就可以构成方法的重载(overload)。
2、方法构成重载的要素:
参数列表:(同名不同参,和返回值类型无关)
1. 要求方法名称必须相同
2. 参数列表至少有一要素不同
参数的个数
参数的类型
参数的类型顺序
3. 和返回值类型无关
三、递归方法
递归方法:一个方法体内调用它自身。
方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制。
递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环。
Stage01 Day04
一、Java中类的概念
类是事物相关属性和行为的集合,可以看成是一类事物的模板,使用事物的属性特征来描述该类事物。( 类是对一类事物的描述,是抽象的。)
定义类:就是定义类的成员,包括属性声明和方法声明。
属性声明:和以前定义变量几乎是一样的,只不过位置发生了改变。在类中,方法外。
方法声明:和以前定义方法几乎是一样的。只不过把static去掉,static的作用在面向对象后面课程中再详细讲解。
注意事项
带static方法,可在main方法中直接调用
面向对象中的方法,由对象去调用,方法可不需要加static
二、Java中对象的概念
是一类事物的具体体现,对象就是类的一个具体实例,对象具备该类事物的属性和行为。( 对象是一类事物的实例,是具体的。)
对象就是从某一类抽取出来的一个具体。
类和对象的关系
类是对,对象的抽象表示,对象是类的一个实例而已
三、面向对象程序设计
面向对象程序设计的重点是类的设计,也就是类的成员的设计。
四、类的声明
类的属性声明
类的方法声明
定义类:就是定义类的成员,包括属性声明和方法声明。
属性声明:和以前定义变量几乎是一样的,只不过位置发生了改变。在类中,方法外。
方法声明:和以前定义方法几乎是一样的。只不过把static去掉,static的作用在面向对象后面课程中再详细讲解。
注意事项
带static方法,可在main方法中直接调用
面向对象中的方法,由对象去调用,方法可不需要加static
五、JVM介绍
JVM(Java Virtual Machine-Java虚拟机)可以理解为是一个基于内存运行的一台虚拟计算机,专门用来编译和解释执行Java的。
它的存储就是JVM内存,我们写的所有类、变量、常量、方法都在JVM内存中。
JVM架构图及各个模块的作用
类装载器子系统:就是负责将class文件加载到内存中的。
运行时数据区:规定了Java应用程序在运行过程中的内存的申请、分配、管理的策略,进而保证了Java应用程序高效稳定的运行。
比如说类中的属性,方法的参数类型,返回值类型,参数的数量在内存中的存储情况都是明确的说明的
执行引擎:Java字节码的执行是由JVM 执行引擎来完成
本地方法接口:Java源码中Native 方法 就是典型的本地方法接口,作用就是融合不同的编程语言为Java所用,它的初衷是融合C/C++程序。
本地方法库:本地方法库的存在就是为了Java应用程序和Java外面的环境交互,这是本地方法存在的主要原因。
虚拟机栈: Java虚拟机栈 Java Virtual Machine Stack,早期也叫Java栈,简称栈,主管Java程序的运行,它保存方法的局部变量、并参与方法的调用和返回。
在调用方法时,JVM会为该方法开辟一个栈帧,存储该方法里的参数,局部变量等等;
每一个方法从调用直到执行完成的过程就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
堆:对于Java应用程序来说, Java堆(Java Heap) 是虚拟机所管理的内存中最大的一块。
此内存区域的唯一目的就是存放对象实例,在虚拟机启动时创建,当执行new关键字时就会在JVM中的堆内存空间中开辟一段内存空间
方法区:方法区(Method Area)它用于存储已被虚拟机加载的class信息。
类加载器将class文件加载到内存之后,将类的信息存储到方法区中。
方法区存储的内容:
(1) 类型信息:
是JVM加载的类型(类Class、接口 interface),JVM必须在方法区中存储以下类型信息:
① 这个类型的全限定名(包名.类名)
② 这个类型直接父类的全限定名
③ 这个类型的修饰符( public, abstract,final)
(2)域信息:
是类中的属性(成员变量),JVM必须在方法区中保存类的所有的成员变量
① 属性名称、属性的类型
(3)方法信息:
② 方法名称、方法的返回类型
③ 方法参数的数量和类型
程序计数器(Project Counter Register):记录字节码指令执行的位置
本地方法栈(Native Method Stack):局部变量:在方法内部声明,使用之前,必须初始化;存储在栈中,一旦方法使用完,变量就失效。
成员变量(属性):定义在类中,方法外,有默认值,存在堆中,对象使用完毕,就被gc()回收。
六、站在JVM上绘制面向对象内存模型图
Stage01 Day05
一、封装的概念
封装就是隐藏类的内部信息(属性和方法),不允许外部程序直接访问,而是通过公有的方法才能完成访问(赋值方法set()和取值方法get()。
所谓的封装,就是利用private关键字去修饰属性或者方法 ,被private关键字去修饰的属性或者方法只能在本类中被访问。
1.属性的封装
将实例变量编写为private,也就是实例变量只能在本类中使用,因为private表示私有的。
2.方法的封装
如果类中的方法只是在本类中被调用,而不允许在外部被访问,那么此时就可以将方法进行封装。
将实例方法编写为private,也就是实例方法只能在本类中使用,因为private表示私有的。
二、类声明的建议
- 若有属性建议private私有
- 提供用来操作属性或者方法的公有的set()和get()方法
- 提供无参数的构造方法
三、构造方法
1、什么是构造方法:
构造方法是一个特殊的方法,主要特殊点如下
构造方法的名字与类的名字一致
它不声明返回值类型。(与声明为void不同)
不能被static、final、synchronized、abstract、native修饰,
不能有return语句返回值
2、构造方法的作用:
完成对属性的赋值
3、构造方法如何执行
在创建对象时执行对应的构造方法,当new时若后面小括号没有内容,则执行无参数的构造方法,否则执行相匹配的带参数的构造方法。
4、创建构造方法的注意事项:
当创建一个类时,建议把无参数的构造方法写上,然后再编写有参数的构造方法,避免当有参存在而认为无参还默认存在而使用无参构造时产生编译错误的行为。
5、构造方法的重载
在同一个类中至少出现2个或者2个以上的参数列表必须不同的构造方法,这里的参数列表包括参数的个数、参数类型、参数类型顺序三要素,三要素若仅有一要素不同,那么就构成方法的重载。
6、对属性赋值的方式
截止到目前,我们讲到了很多位置都可以对类的属性赋值。现总结这几个位
置,并指明赋值的先后顺序。
赋值的位置:
① 默认初始化
② 显式初始化
③ 构造器中初始化
④ 通过“对象.属性“或“对象.方法”的方式赋值
赋值的先后顺序:
- - ② - ③ - ④
四、this关键字
1、说明
this在Java中代表的是当前对象,也就是说:当前谁调用这个方法则这个对象就是谁。
this关键字可以访问本类中的实例变量、实例方法以及本类中的构造方法。
2、this关键字访问本类中的实例变量
3、this关键字访问本类中的实例方法
4、this关键字访问本类中的构造方法
5、注意事项
可以在类的构造器中使用"this(形参列表)"的方式,调用本类中重载的其
它的构造器!
明确:构造器中不能通过"this(形参列表)"的方式调用自身构造器
如果一个类中声明了n个构造器,则最多有 n - 1个构造器中使用了
"this(形参列表)"
“this(形参列表)"必须声明在类的构造器的首行!
在类的一个构造器中,最多只能声明一个"this(形参列表)"
五、static关键字
1、说明
static表示静态的,可以修饰属性、方法、代码块、内部类以及实现静态导入。
2、static关键字修饰全局变量
1)在类中声明的变量,称为属性或者叫做成员变量、或者叫做字段。那么属性面前如果加入static关键字修饰,称为静态变量,也叫做类的变量。
如果属性前面没有编写static关键字,称为实例变量,也叫做对象变量。
2)静态变量的访问方式
类名.静态变量名
对象名.静态变量名
3)static修饰的全局变量(属性)就是类变量,也就是共享数据。
4)静态变量和实例变量的区别:
静态变量对于类而言在内存中只有一个,能被类的所有实例所共享。
实例变量对于类的每个实例都有一份,它们之间互不影响。
3、static关键字修饰方法
1)如果方法前面编写static关键字,称为静态方法,也叫做类的方法。
如果方法前面没有编写static关键字,称为实例方法,也叫做对象的方法。
2)静态方法的特点
①没有对象的实例时,可以用类名.方法名()的形式访问由static修饰的类方法。
②在static方法内部只能访问类的static修饰的属性或方法,不能访问类的非static的结构。
③实例方法中可以访问:静态变量和静态方法,也可以访问实例变量和实例方法
④因为不需要实例就可以访问static方法,因此static方法内部不能有this。
⑤static修饰的方法不能被重写 继承
3)静态方法访问方式
类名.静态方法名
对象名.静态方法名
4、单例 (Singleton)设计模式
1)单例设计模式实现-饿汉式
2)单例设计模式-懒汉式
5、静态导入
六、类的成员之四:代码块
1、代码块定义
代码块是一种常见的代码形式。它用大括号“{}”将多行代码封装在一起,形成一个独立的代码区,这就构成了代码块。
2、分类
Stage01 Day06
一、继承
1、关键字——extends
2、继承的作用
继承的出现,更有利于功能的扩展。
继承的出现,让类与类之间产生了关系,提供了多态的前提。
3、继承的注意事项
1)父类也叫做超类,也叫做基类superclass,子类也叫做派生类subclass
2)子类继承父类时,没有继承父类的构造方法
3)继承要满足的条件:is a(什么什么是什么的一种时)
4)当一个类没有使用extends指定继承哪个父类时,则系统默认继承Object类,在Java中, Object类是所有类的父类也叫做超类,也就是:当继承Object父类时extends Object是可有可无
5)类继承了父类,就继承了父类的方法和属性。
6)
7)Java支持单继承,不支持多继承,但支持多层继承,继承具有传递性
二、方法的重写(@override)
1、注意事项
1)当子类重写父类的方法,再创建子类对象时,调用的是子类重写以后的方法,也就是说:父类中的方法使用不到,但是必须不能删除,原因:删除父类中的方法后,子类也就不能重写,报错。
2)方法重写只能发生在子父类中,方法重写以后,子类中重写的方法,返回值类型,参数名称,参数列表与父类中被重写的方法必须一致。
3)子类与父类中同名同参数的方法必须同时声明为非static的(即为重写),或者同时声明为static的(不是重写)。因为static方法是属于类的,子类无法覆盖父类的方法。
2、重载和重写的区别
3、重写的规则
重写的规则
不能缩小访问权限
返回值类型一致 或者 父类方法返回值类型的子类类型
方法名称必须一致
参数列表必须一致
三、权限修饰符
四、super关键字
this和super的区别
五、子类对象实例化过程
为什么super(…)和this(…)调用语句不能同时在一个构造器中出现?
思路:首先要明白this()与super()各自的功能,再谈两者同时出现在一个构造函数中时,为什么会报错。
首先是不安全,因为在构造函数中,会在第一行声明super(),此时super()默认先调用父类的无参构造,或者super()调用有参构造,然后再完成子类特有属性的初始化。而在子类的构造函数中this()调用的是子类中的其他构造函数,其他构造函数中必然会有默认调用父类无参构造方法,或直接调用有参构造方法的构造函数,此时,同一个子类构造器中声明了两次父类构造函数,即父类初始化了两次,造成不安全的问题。
再者是失去了语句的意义,如果同时在子类构造方法中调用了两次同样的构造函数,编译器不通过。
当创建子类对象时,父类做了什么?
当创建子类对象,先执行父类构造方法,然后再执行子类相匹配的构造方法
Stage01 Day07
一、多态
1、概念
是指同一行为,通过不同的具体事物,具备多种不同的表现形式。
父类的引用 指向子类对象 从左侧像右侧看
子类的对象赋值给父类的引用 从右侧向左侧看
2、多态的语法格式
父类类型 引用名 = new 子类()
Pet cat = 通过Cat来构建动物类对象-Pet pet= new Cat();
dog = 通过Dog来构建动物类对象-pet= new Dog();
3、多态的动态绑定技术
两个类存在extends继承关系后,使用多态构建的对象去调用子类中重写的方法,那么调用的方法显示的虽然是父类的,但是输出的结果却是子类重写以后的。
4、满足多态的条件
第一个:必须存在继承关系
第二个:父类类型 引用名 = new 子类();
第三个:子类必须要重写父类的方法
5、多态的好处
有良好的扩展性。
因为父类类型作为参数时,能够接受所有的子类。
减少代码的冗余性
6、多态中的两种类型转换
1)向上转型
表现形式:当构成多态时,就是向上转型。
Pet cat = new Cat();
Pet dog = new Dog();
向上转型的体现:从右向右左看,是一个由子到父的过程
注意:
当前应用对象名称是父类类型,则只能访问父类中公共的属性和公共的方法,但是优先访问子类重写以后的方法。
多态的动态绑定技术:调用的方法父类的,但是输出的结果却是子类重写以后的。
2)向下转型(由父到子的过程)
Pet cat = new Cat();
Cat newCat = (Cat)(cat);
当构成多态时,如果访问子类中独有的属性或者独有的方法,则就必须进行向下转型,也叫做强制类型转换。
7、注意
8、instance of
在进行向下转型之前,必须先判断,判断被转换的父类的引用与预期要转换的类型是否一致,一致就执行转换操作,反之不执行
二、Object类
Object类是所有Java类的根父类
如果在类的声明中未使用extends关键字指明其父类,则默认父类为java.lang.Object类
1、Object类中的主要方法
2、==和equals的区别
3、to String方法
子类在没重写之前toString()方法时,返回的结果是对象内存地址,而在开发中,经常需要将对象属性值以字符串的形式进行显示,因此需要重写它。
本质:子类中没有重写toString()方法时,输出的就是对象地址,子类中重写toString()方法了就是输出对象中所有属性的值,其实就是类似于之前将print()方法改为重写toString()
三、包装类
针对八种基本数据类型定义相应的引用类型—包装类(封装类)
有了类的特点,就可以调用类中的方法,Java才是真正的面向对象
1、创建包装类的对象
//1) 所有的包装类对象都可以根据 基本类型数据创建
Byte b1 = new Byte((byte) 55);
Short s1 = new Short((short) 188);
Integer i1 = new Integer(789);
Long g1 = new Long(79846513);
Float f1 = new Float(45.78F);
Double d1 = new Double(3.12);
Character c1 = new Character('汉');
Boolean flag = new Boolean(true);
//2) 除以Character外,其他包装类对象可以根据 String字符串创建
Byte b2 = new Byte("22");
Integer i2 = new Integer("746851");
Double d2 = new Double("789465.8465");
//注意: 字符串要符合对应的数字格式
//Integer i3 = new Integer("hello"); //NumberFormatException
//可以把非"true"的字符串都转换为false
//Boolean flag2 = new Boolean("true");
//Boolean flag2 = new Boolean("false");
Boolean flag2 = new Boolean("hello");
System.out.println(flag2);//false
2、包装类常用方法
1)所有的包装类底层都有一个value属性 保存对应的基本类型数据, 即i1的value属性保存456, i2的value属性保存123。
Byte bb1 = i1.byteValue();
System.out.println(bb1); //-56
byte bb2 = i2.byteValue();
System.out.println( bb2 ); //123
2)static int compare(int x, int y) 比较两个基本类型数据的大小,如果前面的数大返回正数, 后面的数大返回负数, 相等返回0
System.out.println( Integer.compare(10, 20)); //-1
System.out.println( Double.compare(8,4.5)); //1
System.out.println( Character.compare('A', 'b')); //-33
System.out.println( Boolean.compare(false, true)); //-1, true大于false
3)int compareTo(Integer anotherInteger) 比较两个包装类对象的大小
所有的包装类都实现了Comparable接口, 重写了compareTo()方法, 包装类对象比较大小时, 其实就是比较它的value属性值 的大小
*/
System.out.println( i1.compareTo(i2)); //比较i1对象的value属性值456 与 i2对象的value属性值123 的大小
4)static int parseInt(String s) 把字符串转换为int整数
*/
int num = Integer.parseInt("789");
double dd = Double.parseDouble("45.784");
boolean flag = Boolean.parseBoolean("hello");
//Character没有parseXX()方法
5)提供静态方法创建包装类对象
从JDK9开始, 包装类的构造方法都使用@deprecated注解修饰为已弃用, 已过时, 即从JDK9开始,不建议使用构造方法创建包装类对象了,
再使用构造方法时会在方法中间添加一条横线表示已弃用, 建议使用静态方法valueOf()创建
static Integer valueOf(int i)
static Integer valueOf(String s)
*/
Integer i3 = Integer.valueOf(741);
Integer i4 = Integer.valueOf("852"); //同样字符串要符合对应的数字格式
Double aDouble = Double.valueOf(78.87);
Boolean aBoolean = Boolean.valueOf("True");
Character a = Character.valueOf('A');
6)声明一个字符a,将其转换为大写并进行输出
7)除了Character类之外,其它所有包装类都具有parseXxx()静态方法可以将字符串转换为对应的基本类型
3、拆、装箱
装箱-由基本类型到包装类型
由小到大
自动数据类型转换
拆箱-由包装类型到基本类型
由大到小
强制数据类型转换
举例: Integer i1 = 789; //自动装箱 , java会根据int整数789创建一个Integer对象, 把这个对象的引用赋值给i1
int num = i1; //自动拆箱, 把i1引用的Integer对象的value属性值赋值给num
注意: Integer i3 = 69;
Integer i4 = 69;
System.out.println(i3 == i4); //true
Java认为-128~127范围内的整数使用最频繁, 所以这个范围内整数自动装箱后, 采用享元模式, 类似于String字符串字面量。
四、final关键字
Stage01 Day08
一、抽象类
1、定义
2、注意事项
抽象类中既可以存在普通的方法,还可以存在抽象方法
抽象方法必须没有方法体,直接以英文分号结束
抽象方法必须在抽象类中
当子类继承抽象类时,子类必须重写抽象类中的所有抽象方法,否则子类也是抽象类
3、什么时候时候将类编写为抽象类
当父类中的方法不需要做具体实现(没有方法体),而只是提供一个方法,把具体代码的实现交给子类重写以后实现时,则就可以将类编写为抽象类
随着继承层次中一个个新子类的定义,类变得越来越具体,而父类则更一般,更通用。
二、接口
接口使用interface关键字声明,其中interface表示接口
接口中的抽象方法默认有public abstract
1、接口的概念
Java中的接口就是一种统一了实现子类的开发标准。但凡符合接口标准的子类都可以和接口做适配。
2、注意事项
与继承关系类似,接口与实现类之间存在多态性
3、抽象类和接口的区别
相同点
都不能创建对象,其实:抽象类和接口都是多态的一种形式
抽象类和接口中都可以编写抽象方法
子类或实现类都必须要重写抽象类或接口中的所有的抽象方法,否则子类或实现类就是抽象类
不同点
抽象类
使用abstract关键字
抽象类中包含:普通类中包含的所有内容,也可以包含抽象方法
子类继承抽象类,并且是单继承
抽象类的出现就是为了统一标准,但是有单继承局限
接口
使用interface关键字
在JDK8.0中,接口包含:抽象方法(默认有public abstract)、公有静态常量(默认有public static final)、public static修饰的方法、public default修饰的方法
实现类实现接口,并且是多实现
接口的出现是为了统-标准,同时没有单继承局限
接口也弥补了Java单一继承的弱点,也就是类可以实现多个接口。
三、设计模式
1、模板设计模式
模板方法设计模式,其主要思想是设计一个模板,当一个类需要此模板中的具体方法时,继承此模板,实现模板的价值。模板设计模式主要是对继承知识的应用。
2、代理设计模式
代理设计模式的主要思想是将代理人和被代理人的公共方法提取,代理人执行方法同步给被代理人从而实现代理人和被代理人的数据同步,主要应用的知识点是接口
静态代理:将代理人和被代理人的公共方法提取,目的是使被代理人无需管理但是也会被同步。在代码逻辑上看,创建接口,代理人和被代理人实现接口,但是代理人可以定义其他方法,为了同步,需要在代理人类中创建被代理人类的属性和以被代理人为参数的构造方法。
动态代理:动态代理主要解决了静态代理的拓展问题,在静态代理中,当多个类需要代理时,那么需要创建多个接口,多个代理类,各个类的耦合度较高。那么用动态代理只需将需要代理的类名传入动态代理的方法中从而实现代理。
3、简单工厂模式
简单工厂设计模式是用来生产同一等级结构中的任意产品,但是对于新增产品时需要修改已有代码,扩展性较差
4、工厂方法模式
工厂方法设计模式的主要思想就是将创建对象的内容隐藏只暴露一个接口从而实现了创建对象和调用方法的分离
工厂方法设计模式是用来生产同一等级中的固定产品,支持新增同一等级下的产品,但是在生产其他品种的产品时扩展性较差
5、抽象工厂模式
抽象工厂设计模式是用来生产不同品种的全部产品,当需要新增产品时,无能为力,但是在新增新的品种时会展现其模式的特点
四、内部类
1、内部类的定义
当一个类的定义出现在另一个类的类体中时,那么这个类叫做内部类,而这个类所在的类叫做外部类。
2、内部类解决的问题
①可让类和类之间的继承/实现更简化
②让接口和抽象类也可以new
3、内部类的分类
(1)成员内部类
【1】非静态内部类
①在A类中申明了一个B类,此B类就在A的内部,并且在成员变量的位置上,所以就称为成员内部类,由于此时的内部类没加static,所以叫做非静态内部类。
②使用方式
1.普通内部类和普通类一样可以定义成员变量、成员方法以及构造方法等。
2.普通内部类和普通类一样可以使用final或者abstract关键字修饰。
3.普通内部类还可以使用private或protected关键字进行修饰。
4.普通内部类需要使用外部类对象来创建对象。
5.如果内部类访问外部类中与本类内部同名的成员变量或方法时,需要使用类名.this.的方式。
③成员内部类能干什么?
1.访问外部类的所有成员(这里的属性包括私有的成员变量,方法)
如果内部类中的变量名和外部类的成员变量名一样,要通过创建外部类对象 "."属性来访问外部类属性,通过this.属性访问内部类成员属性
[2]静态内部类
1、静态内部类能够直接被外部类给实例化,不需要使用外部类对象
2、静态内部类中可以声明静态方法和静态变量,但是非静态内部类中就不可以声明静态方法和静态变量
【3】局部内部类
1.局部内部类只能在该方法的内部使用。
2.局部内部类可以在方法体中直接创建对象。
3.局部内部类不能使用访问控制符和static关键字修饰符。
4.局部内部类可以使用外部方法的局部变量,但是必须是final的,当没有加final时,默认也是final的。(由于局部内部类是将该变量复制一份到内部使用的,担心在使用过程中局部内部类的外面的代码对该变量进行了修改,所以要用final修饰。)
【4】总结
Stage01Day09
一、数组
1、声明方式
(1)静态初始化
数据类型[] 数组名 ={元素1,元素2,元素3,……,元素n};
int[] nums = {1,2,3,4,5};
(2)动态初始化
数据类型[] 数组名字 = new 数据类型[数组长度];
int[] ints = new int[5];
2、数组元素的默认初始化值
3、数组中常见的异常
4、数组中元素的查找
线性查找:循环遍历,逐个比较
二分查找原理:————要求数组必须是有序的
每一次都去获取数组的中间索引所对应的元素,然后和要查找的元素进行比对,
如果相同就返回索引如果不相同,就比较中间元素和要查找的元素的值:
1.如果中间元素的值大于要查找的元素,说明要查找的元素在左侧,那么就从左侧按照上述思想继续查询(忽略右侧数据),
2.如果中间元素的值小于要查找的元素,说明要查找的元素在右侧,那么就从右侧按照上述思想继续查询(忽略左侧数据
public class ErFenSel {
public static void main(String[] args) {
int[] intArr = new int[]{93,94,95,96,97,98,99};
//在数组中有效的元素索引位置范围内查询目标元素
int dest = 99;
int head = 0;
int end = intArr.length - 1;
while(head <= end){
int middle = (head + end) / 2;
if(dest == intArr[middle]){
System.out.println("找到了指定的元素,位置为:"+middle);
break;
}else if(dest < intArr[middle]){
end = middle - 1;
}else{
head = middle + 1;
}
}
}
}
5、 排序算法
冒泡排序:
public class MaoPao {
/**
* 1. 静态初始化一维数组{10,20,11,35,6},进行冒泡排序
*/
public static void main(String[] args) {
int[] arr = {10,20,11,35,6};
for(int i = 1; i <= arr.length - 1 ; i++) {
boolean swapped = false;
for (int j = 0; j < arr.length-i; j++) {
int temp;
if (arr[j] > arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1]=temp;
swapped = true;
}
}
if (!swapped){
break;
}
}
for (int j = 0; j < arr.length; j++) {
System.out.println(arr[j]);
}
}
}
选择排序
快速排序算法
private static void quickSort(int[] arr, int leftIndex, int rightIndex) {//0 7
//未在合法索引范围内进行快排,直接return结束排序
if (leftIndex >= rightIndex) {
return;
}
int left = leftIndex;//左指针-0
int right = rightIndex;//右指针-7
//待排序序列中的第一个元素作为基准元素(也就是索引为0的元素-arr[0])
int key = arr[left];//key-基准元素
//从左右两边交替扫描,直到left = right 进行基准元素的归位
while (left < right) {//0 7
//从右往左扫描,找到第一个比基准值小的元素
while (right > left && arr[right] >= key) {
right--;
}
//找到比基准元素小的元素,将该元素arr[right]放入坑中(原有索引为0的位置)arr[left]中
arr[left] = arr[right];
//从左往右扫描,找到第一个比基准值大的元素
while (left < right && arr[left] <= key) {
left++;//1
}
//找到这种元素将arr[left]放入arr[right]中
arr[right] = arr[left];
}
//基准值归位
arr[left] = key;
//对基准值左边的元素进行递归排序
quickSort(arr, leftIndex, left - 1);
//对基准值右边的元素进行递归排序。
quickSort(arr, right + 1, rightIndex);
}
public static void main(String[] args) {
/* int[] array = {6,72,113,11,23};*/
int[] array = {4,7,6,5,3,2,8,1};
quickSort(array,0 , array.length -1);
System.out.println("排序后的结果");
System.out.println(Arrays.toString(array));
}
}
二、数组工具类:Arrays的使用
6、copyof(T[],int newLength):将源数组中的元素拷贝到新数组中
**
* 定义方法,实现数组的复制, 通过参数接收一个数组
* 1.声明一个方法
* 2)带返回值(int[]),带参数的(int[] ints)
* 3) 方法内部,优化写扩容的代码
* 1) 定义更大的数组
* 2) 把原来数组元素复制到大的数组中(优化)
* 3) 返回这个大的数组
*/
public class ArrayDilatationOptimize {
//定义方法,实现数组的复制, 通过参数接收一个数组,
private static int[] copyOf(int[] ints) {
//对ints数组扩容
//1) 定义更大的数组
int[] bigger = new int[ints.length * 2]; //按2倍大小扩容
//2) 把原来数组元素复制到大的数组中
/*for (int i = 0; i < ints.length; i++) {
bigger[i] = ints[i];
}
ints = bigger; //对形参重新赋值,跟实参没有关系*/
//bigger = Arrays.copyOf(ints, ints.length * 2);
//System.arraycopy(ints,0,bigger,0,ints.length);
//arraycopy方法使用native修饰,只有方法声明没有方法体, 这个方法体是用C/C++实现的.
即在Java语言中可以调用其他语言编写 的代码
//3) 返回这个大的数组
return bigger;
}
public static void main(String[] args) {
int[] ints = {12, 34, 45, 56, 67, 87};
//调用copyOf方法,把返回的大数组再赋值给ints
ints = copyOf(ints);
//遍历ints数组
for (int anInt : ints) {
System.out.print(anInt + " ");
}
System.out.println();
}
}
三、动态数组
1、扩容
2、add()方法
3、remove()方法
4、set()
5、getElement()方法
6、printAll()方法
四、对象数组
1、定义
类类型,作为数组的数据类型时,构建的数组就是对象数组。
2、System.arraycopy()方法的使用
五、二维数组
1、定义
所谓二维数组,可以简单的理解为是一种“特殊”的一维数组,它的每个数组空间中保存的是一个一维数组。
2、初始化方式
(1)静态初始化
2、多变形参 ——int...arrs
- 使用可变参数后
- 可以不传入;
- 也可以传入多个参数;
- 也可以直接传入数组;
StageDay10
异常
1、异常的定义
在Java语言中,将程序执行中发生的不正常情况称为“异常”。 (开发过程中的语法错误和逻辑错误不是异常)
2、异常的处理机制一:try-catch-finally
(1)格式
把可能产生的异常的代码放入try语句中,如果放入的代码真的有问题,就会执行catch语句,告诉我们程序有异常,并打印输出具体的异常名字是什么。反之,如果放入的代码没有任何问题,那么catch语句就不会执行。把一定要执行的代码放入到此finally语句中。
注意:try和catch不一定要同时出现,但是没有catch时,一定要提供finally。当try中有return语句时,finally中的语句也会先于return执行;
(2)捕获异常的有关信息
3、异常的处理机制二:throws
使用格式