面向对象(OOP)
关注的焦点是类
代码结构:以类为组织单位,每种事物都具备自己的属性和行为/功能
面向对象设计程序时,从宏观上分析程序有哪些功能。然后对功能进行分类,把不同的功能封装在不同的类中,是一种宏观的设计。
但是到具体实现,仍然离不开面向过程。
两者相辅相成
类和对象
· 类
具有相同特征的事物的抽象描述,是抽象的、概念上的定义
先根据客观的事物进行抽象(设计为程序),然后由抽象创造出具体,最终使用的是具体
类是抽象概念,不能直接拿来使用,若要使用,要创建类的实例
过程:
第一步:发现类
第二步:定义类的成员变量
第三步:定义类的成员方法
第四步:使用类创建对象,最终使用的是对象
· 对象
实际存在的该类事物的每个个体,是具体的,因而也称为实例
对象是类的实例,是以类为模板,在内存中创建出的一个实际存在的实例(对象)
· 如何创建对象:使用new关键字
new Car() 使用new关键字创建一个具体的对象,对象存在内存中
同一个类的每个对象有不同存储空间
· 类与对象的关系
类是模板,是定义
对象是具体实例
· 构造方法
特点:方法名字与类名相同
没有返回值,不需要void修饰
作用:为刚创建的对象成员变量进行初始化赋值
创建对象时,调用的是无参的构造方法初始化对象成员,先赋予默认值,然后
· 方法重载
在一个类中,有多个名称相同的方法
如何在调用时区分同名的方法:
通过方法的参数的个数,类型,顺序区分方法
方法的重载与返回值类型没有关系
在类中创造的方法有参时,系统自带的无参的创造方法就会被覆盖。若想要用无参的创造方法进行调用,需在类中加上无参的创造方法的结构。
对象与引用
值传递--基本类型作为参数传递,形参改变后,实参是没有影响,使用实参的值,填充了形参,是两个独立的变量。
引用类型传递--引用数据类型作为参数传递,传递的只是对象的地址,实参和形参指向的是同一个对象,任何一方改变对象的值,另一方也会改变。
this关键字
在类中用来表示当前正在访问的对象,this.成员变量名--显示的访问当前对象的成员变量
在类中的某个构造方法中,使用this调用另一个构造方法
static关键字
static--静态,可以用来修饰类的成员变量,成员方法,代码块,内部类等
static静态属性在内存中只存在一份,所有对象共享这一份静态成员变量
static修饰属性(成员变量)
static关键字修饰的属性特点:
1、静态成员变量也称为类变量,在内存中只有一份,所有对象可以共享,一般情况下,将类中所有对象相同的属性设置为静态的。
2、static修饰内容,随着类的加载而加载,类只需被加载了就可以直接通过类名访问。
3、优先于对象存在
4、静态成员被所有的对象共享
推荐直接用类名去访问该静态成员
一旦方法中,使用了非静态的成员变量,那么此方法就不能定义为静态的,非静态的方法中可以使用静态的成员变量。
static修饰成员方法
修饰的成员方法也称为类方法,可以直接使用类名访问。
在静态的方法中只能访问静态的成员变量,非静态的方法中可以使用静态的成员变量。
访问权限修饰符
访问权限修饰可以修饰类、成员变量、成员方法、内部类。
public:公共权限,在任何地方都可以访问到
protected:受保护权限,在本类中,同包的其他类中可以访问到,还可以在其他包中的子类访问
(什么都不写):默认权限,在本类中,同包的其他类中可以访问到
private:私有权限,在本类中可以访问到
变量的分类
数据类型:基本类型变量 byte short int long float double char boolean 8种关键字声明的
引用类型变量 类 数组 持有的是对象的引用地址
按照位置分:
成员变量:定义在类中,可以使用权限修饰符修饰
在构造方法中进行自动的初始化赋值
生命周期:
非静态:随着对象的创建而创建,随着对象的销毁而销毁
静态的:随着类的加载而加载,随着类的销毁而销毁
存储的位置:
非静态:堆
静态的:方法区
局部变量:定义在方法中,不可以使用权限修饰符修饰
必须我们自己进行初始化
生命周期:方法调用创建,方法运行结束销毁
存储的位置:栈
三大特征:
1、封装
一般意义的封装,例如将重复出现的代码抽取成一个函数,称为代码的封装(包装)。
将类的某些信息使用不同的访问权限修饰符隐藏在类内部,不让外界直接访问操作,而是通过类中向外提供的特定的方法来实现对隐藏的信息进行操作访问。方便加入控制语句,主动权就在我们类自己手中。
2、继承
就是将同一类事物中共性的属性和行为进行抽取,定义在一个类中(基类)
其他类可以继承基类,就可以拥有基类中的功能,实现代码的复用性。
以及可以在子类中扩展子类自己特有的功能,而不影响其它类。
子类使用 extends 关键字继承另一个类(只能单继承,可以间接多继承)
特点:
1、提高了代码的复用性
2、减少了代码的冗余
3、增强了程序的扩展(在子类中扩展自己特有的功能并且不影响其他)
方法重写:
当父类中方法的实现不能满足子类需求时,可以在子类中对父类的方法进行重写(覆盖),这样调用时,就会调用子类中重写的方法。
子类重写的方法的结构 与 父类方法的结构必须一致
方法名,参数列表,返回值必须一致
3、多态
同一种事物,在不同时刻表现不同的状态
父类的引用变量指向子类对象(前提 必须要有继承关系,构成多态)
多态也称为向上转型,将子类类型转为父类类型
两个不同时间段:
1、编译期:写代码时 类型时Animal(父类类型)
2、运行期:运行代码时 类型是具体的子类类型
优点:
可以提高程序的扩展性
多态场景下:
成员方法调用:编译看左边,运行看右边
静态成员方法调用:编译和运行都看左边。因为多态情况下,静态方法不存在方法重写
成员变量调用:编译和运行都看左边
将子类类型都转为父类类型,便于程序的扩展
instanceof 表示父类类型中持有实际类型 是否是指定的子类类型
父类类型 instanceof 具体子类类型。父类类型与指定类型相同返回true 否则返回false
final 关键字
用于修饰类,方法,参数,成员变量(修饰后变常量)
1、final 修饰的类是不能被继承的。所以不能修饰抽象类。例如 java中String类(String类是由final修饰的)
2、final修饰的方法不能被重写
3、final修饰方法的参数,参数值在方法中不能被改变的。
4、final修饰的成员变量值不能改变,因此称为常量
情况1:在类定义时,值就已经确定并且直接赋值,复制后不能改变,建议用static去修饰final
情况2:在类定义时,值不明确,必须在创建对象后,在构造方法对其进行赋值,每个对象中拥有一个常量
接口
接口是计算机领域的名词,表示一种功能的定义
从本质上讲,接口可以看做是一种特殊的抽象类,里面也包含抽象方法。
接口不能被创建对象,不能被其它类实现,不能重写抽象方法
主要也是用来定义功能的。
接口在jdk8后可以定义静态常量,抽象方法,静态方法,默认方法
interface 关键字修饰 接口
类通过implements关键字实现接口
一个类可以直接继承一个类,一个类可以实现多个接口,一个接口还可以继承多个接口。
API
(Application Programming Interface)应用程序编程接口
API: 指的就是官方给开发人员提供的一个说明文档,对语言有哪些类,类中有哪些方法进行说明.
Object类
java.lang.Object
是java类体系结构中最顶层的类
Object可以表示java中任意的类.
Object类中方法:
toString()
输出一个对象,但对象在内存中存储,是不能输出的,当输出一个对象时,会默认调用此对象的toString(),如果类中没有定义toString(),会调用Object类中toString(),Object类中toString(),是把对象在内存的哈希值返回(以16进制返回)
我们自己类可以对Object类中的toString()进行重写,后面调用时,就调用我们自己类中的toString()
equals(Object obj)
Arrays类
java.util.Arrays类用于操作数组工具类,里面定义了常见操作数组的静态方法
Arrays类中方法:
比较:equals(type[]a,type[]a1)
排序:sort(type[] a)
自定义对象排序 自定义类实现Comparable接口 重写compareTo方法
二分查找:binarySearch(type[] a, type key)
数组复制:copyOf(int[] a, int newLength)
toString(type[] a)
基本数据类型包装类
自动拆箱:把引用类型 转为 基本类型
自动拆箱 会默认自动的调用intValue()方法
自动装箱:把基本类型 转为 引用类型
自动装箱时,会默认自动调用valueOf()方法
在valueof()中如果比较的基本数据值在-128 — 127之间,会从缓存数组中直接取出一个Integer对象,减少创建次数
如果两个值相同,获取的是同一个对象
基本类型值如果不在-128 — 127区间,每次都创建一个新Integer对象返回
String类
java.lang.String
java中所有字符串都是此类的实例
"abc"-->字符串对象 底层是一个char数组 private final char value[]; 字符串对象创建方
1.String s = "abc";
创建时,先去字符串常量池查找有没有相同值的对象,如果没有,就创建一个字符串对象,并返回地址 如果字符串常量中已存储,不用创建新的,直接返回已存在对象的地址
2.String s1 = new String("abc");
new 每次都是在堆中创建新的字符串对象
构造方法
String()
String(String s)
String(byte[] bytes) 把字符数组转为字符串 getbytes()
String(char[] chars) 把char数组转为字符串 toCharArray()
判断功能
boolean equals(Object obj) 比较字符串对象中内容是否相等
boolean equalsIgnoreCase(String str) 比较字符串对象中内容是否相等 忽略大小写
boolean contains(String str) 判断字符串中是否包含指定的子串
boolean isEmpty() 判断字符串值是否为""
boolean startsWith(String prefix) 判断是否以指定的字符串开头
boolean endsWith(String suffix) 判断是否以指定的字符串结尾
获取功能
int length() 获取字符串长度
char charAt(int index) 获取指定位置上的字符
int indexOf(String str) 返回的指定字符首次出现的位置
int indexOf(String str,int fromIndex) 从指定的位置开始查找,返回的指定字符首次出现的位置
int lastIndexOf() 从后向前查找,返回的指定字符串首次出现的位置
String substring(int start) 从指定的开始位置开始截取一个字符串副本到完
String substring(int start,int end) 从指定的开始位置开始截取一个字符串副本到到指定位置(不包含结束位置)
转换功能
byte[] getBytes() 把字符数组转为字符串
char[] toCharArray() 把char数组转为字符串
static String valueOf(char[] chs)
String toLowerCase() 将英文字母转为小写
String toUpperCase() 将英文字母转为小写
String concat(String str) 拼接指定的字符串内容到原字符串末尾 返回一个新的字符串对象
Stirng[] split(分割符) 将一个字符串用指定的分隔符拆分成一个字符串数组
替换功能
String replace(char old,char new)
String replace(String old,String new) 用新内容替换字符串中指定的字符串
replaceAll(String regex, String replacement) 用新内容替换字符串中正则表达式匹配的字符串
replaceFirst(String regex, String replacement) 用新内容替换字符串中正则表达式匹配的字符串 只替换第一个 String trim()去除字符串两空格
String、StringBuffer、StringBuilder的区别:
String:是一个值不可以改变的字符串
StringBuffer:值可以改变且不需要创造新对象,方法上都加了锁,是在多线程(任务)执行时是线程安全的
StringBuilder:值可以改变且不需要创造新对象,由于方法上都没有加锁,在多线程(任务)执行时是线程不安全的,适合多线程
Math类
java.lang.Math提供了一系列静态方法用于科学计算;其方法的参数和 返回值类型一般为double型。
abs 绝对值
sqrt 平方根
pow(double a, double b) a的b次幂
max(double a, double b) 求两个数的最大值
min(double a, double b) 求两个数的最小值
集合
单列集合
一次就放进去一个值(对象)
Collection接口,定义了单列集合共有的方法
List
可以有重复元素
ArrayList 数组列表
底层有一个数组,可以动态扩展数组长度,并提供一个一系列方法操作。
查询 快;中间增加、删除 慢
LinkedList 链表列表
底层是一个链表结构
查询 慢;增加、删除 快
Vector 数组列表 线程安全的
Set
不可以有重复元素
HashSet
元素是无序的 通过hashcode和equals方法判断元素是否重复
TreeSet
可以排序 实现Comparable接口,重写comparableTo()判断大小以及是否重复
双列集合
键 值
Map接口,数据存储是"键:值"的形式存储键不能重复的,值可以重复通过键可以找到值一个键只能映射到一个值
HashMap
键是无序的HashMap可以存储一个为null键,多个为null的值
HashMap底层原理:
TreeMap
键可以排序键元素类型必须实现Comparable接口,重写comparableTo()
Hashtable
底层实现也是用到key的哈希值,计算位置判断元素是否重复方法上都添加了synchronized锁Hashtable中不能存储为null的键和为null的值
集合结构图
异常
指的是程序在执行过程中,出现的非正常情况,如果不处理最终会导致 JVM的非正常停止。
异常指的并不是语法错误。语法错了,编译不通过,根本不能运行。
异常的抛出机制
Java中把不同的异常用不同的类表示,一旦发生某种异常,就创建该异常类型的对象,并且抛出。然后程序员可以捕获到这个异常对象,并处理;如果没有捕获这个异常对象,那么这个异常将会导致程序终止。
Throwable
java.lang.Throwable类是Java程序执行过程中发生的异常事件对应的类的根父类。
Throwable中的常用方法:
public void printStackTrace():打印异常的详细信息。
public String getMessage():获取发生异常的原因。
Throwable可分为两类:Error和Exception。
分别对应着java.lang.Error java.lang.Exception两个类。
Error:Java虚拟机无法解决的严重问题。
StackOverflowError:栈内存溢出
OutOfMemoryError:堆内存溢出
Exception: 其它因编程错误或偶然的外在因素导致的一般性问题,需要使用针对 性的代码进行处理,使程序继续运行。否则一旦发生异常,程序也会挂掉。
异常处理
在编码时,就针对可能出现问题的代码(经验问题)
预习编写一些处理机制
程序运行
出现异常
执行处理机制
继续运行后续的程序
try{
编写可能出现异常的代码
}catch(异常类型){
处理机制
getMessage() 获取异常信息,返回字符串
printStackTrace() 获取异常类名和异常信息,以及异常出现在程序中的位置。
}finally{
必须执行的代码
}
常见的异常
ArithmeticException 算术异常:在做一些数据之间的运算,出现违背运算规则时。
ArrayIndexOutOfBoundsException 数组索引越界异常:给出的索引不在数组的索引范围内时。
StringIndexOutOfBoundsException 字符串索引越界异常:取出指定字符对字符串给出错误的索引时。
ClassCastException 类型转换异常:字节大的类型向类型小的类型转换时
NumberFormatException 数字格式化异常:当前数据类型格式不可转换成所需要的类型时
NullPointerException 使用null中的方法/属性 一般在java中表示为 空指针异常
throws 关键字
异常类型声明表示此方法中可能会出现给定的异常,并且该方法不处理异常
谁调用谁处理
异常(Exeception)分为:
检查期异常:在编译期问就会主动提示程序员要进行处理的异常
运行期异常:在编译期间不会主动提示程序员进行处理的异常
区别:在于异常类有没有继承RuntimeException
throw 关键字
在方法体中,抛出一个具体的异常对象,该方法终止运行,在异常对象中的构造方法中自定义异常原因
自定义异常
public class 异常类名 extends Exception/RuntimeException{
public 异常类名(String message){
super(message);
}
}
JDBC
java database connection java数据库连接
jdbc连接数据库步骤
1.在项目添加jar文件
2.加载驱动类 Class.forName("com.mysql.cj.jdbc.Driver");
3.建立与数据库的连接,获得连接对象
String url = "jdbc:mysql://127.0.0.1:3306/schooldb?serverTimezone=Asia/Shanghai";
String user = "root";
String password = "root";
Connection connection = DriverManager.getConnection(url,user,password);
4.发送sql
方法一:创建Statement类对象
Statement st = connection.createStatement();
st.executeUpdate("INSERT INTO student(NAME,gender,birthday,phone,address,reg_time,majorid)"+
"VALUES('"+name+"','"+gender+"','"+birthday+"','"+phone+"','"+address+"',now(),"+majorid+")");
方法二:创建PreparedStatement类对象
PreparedStatement ps = connection.prepareStatement("DELETE FROM student WHERE num = ?");
ps.setObject(1,num);
ps.executeUpdate();
PreparedStatement 和 Statement 的区别
相同点:都是向数据库发送sql
Statement:将参数直接拼接到sql中,写起来麻烦,安全性差,可以在参数中拼接 or 1=1
PreparedStatement:先用?占位,然后通过setObject方法赋值,写起来不用拼接字符串,安全可靠的
在赋值时进行检测,可以防止sql注入攻击
5.如果执行查询操作, 接收包装查询结果
//查询操作
ResultSet rs = ps.executeQuery();//将查询结果封装到一个ResultSet对象中,需要将ResultSet对象中的数据封装到对应的对象中
//next() 如果结果集中有数据返回true,否则返回false
Student student = null;
while(rs.next()){
student = new Student();
//将结果集中数据封装到想要的对象中
student.setNum(rs.getInt("num"));
student.setName(rs.getString("name"));
student.setGender(rs.getString("gender"));
student.setBirthday(rs.getDate("birthday"));
student.setPhone(rs.getString("phone"));
student.setReg_time(rs.getTimestamp("reg_time"));
student.setMajorid(rs.getInt("majorid"));
}
6.关闭与数据库连接
rs.close();
ps.close();
connection.close();
数据库
存储管理数据的仓库 sql
DDL
数据(结构)定义语言DDL(Data Definition Language),是用于创建和修改数据库表结构的语言。
常用的语句:create,alter,drop,rename
创建,删除数据库
创建数据库并设置编码格式 CREATE DATABASE [if not exists] 数据库名 [ CHARSET utf8];
删除数据库 DROP DATABASE 数据库名 / [IF EXISTS数据库名];
修改字符集 ALTER DATABASE 数据库名 CHARSET gbk;
主键: 在一张表中代表唯一的一条记录,不能为空,不能重复
约束: PRIMARY KEY 设置主键约束
NOT NULL 不能为空约束
UNIQUE 唯一性约束
检查约束 设置条件
外键约束
主键自动增长,设置为自动增长时,只能为整数类型:AUTO_INCREMENT 默认值 DEFAULT default_value
字段注释: comment '注释'
创建表语法: CREATE TABLE 表名(列名 数据类型 [约束] [默认值] [ 注释],......)
删除表 DROP TABLE [if exists ]表名
修改表名 RENAME TABLE 旧表名 TO 新表名
复制表结构 CREATE TABLE 新表名 LIKE 被复制表名;
DML
数据操纵语言DML(Data Manipulation Language)
常用语句: insert,delete,update
插入数据
方式1: INSERT INTO 表名(列1,列2……,列n) VALUES(值1,值2…..,值n);
方式2: INSERT INTO 表名 set 列名1=值1,..列名n=值n;
方式3: INSERT INTO 表名(列1,列2……,列n) VALUES(值1,值2…..,值n),(值1,值2…..,值n);
方式4:INSERT INTO 表名(列1,列2……,列n) 查询语句(查询的列数与插入列数匹配)
修改数据
UPDATE 表名 SET 列名 = ‘新值’WHERE 条件
删除数据
DELETE FROM 表名 WHERE 条件
清空整张表
TRUNCATE TABLE 表名;
DQL-基础查询
DQL(Data Query Language)数据查询语言查询是使用频率最高的一个操作, 可以从一个表中查询数据,也可以从多个表中查询数据。
查询结果处理: 特定列查询:select column1,column2 from table
全部列查询: select * from table
算数运算符:+ - * /
排除重复行: select distinct column1,column2 from table
查询函数:select 函数;
字符函数
length():获取参数值的字节个数
char_length()获取参数值的字符个数
concat(str1,str2,.....):拼接字符串
upper()/lower():将字符串变成大写/小写
substring(str,pos,length):截取字符串 位置从1开始
instr(str,指定字符):返回子串第一次出现的索引,如果找不到返回0
trim(str):去掉字符串前后的空格或子,trim(指定子串 from 字符串)
lpad(str,length,填充字符):用指定的字符实现左填充将str填充为指定长度
rpad(str,length,填充字符):用指定的字符实现右填充将str填充为指定长度
replace(str,old,new):替换,替换所有的子串
逻辑处理
case when 条件 then 结果1 else 结果2 end; 可以有多个when
ifnull(被检测值,默认值)函数检测是否为null,如果为null,则返回指定的值,否则返回 原本的值
if函数:if else的 效果 if(条件,结果1,结果2)
数学函数
round(数值):四舍五入
ceil(数值):向上取整,返回>=该参数的最小整数
floor(数值):向下取整,返回<=该参数的最大整数
truncate(数值,保留小数的位数):截断,小数点后截断到几位
mod(被除数,除数):取余,被除数为正,则为正;被除数为负,则为负
rand():获取随机数,返回0-1之间的小数
日期函数
now():返回当前系统日期+时间
curdate():返回当前系统日期,不包含时间
curtime():返回当前时间,不包含日期 可以获取指定的部分,年、月、日、小时、分钟、秒 YEAR(日期列),MONTH(日期列),DAY(日期列) ,HOUR(日期列) ,MINUTE(日期列) SECOND(日期列)
str_to_date(字符串格式日期,格式):将日期格式的字符转换成指定格式的日期
date_format(日期列,格式):将日期转换成字符串
datediff(big,small):返回两个日期相差的天数
分组函数
功能:
用作统计使用,又称为聚合函数或统计函数或组函数
分类:sum 求和、avg 平均值、max 最大值、min 最小值、count 计数 (非空)
1.sum,avg一般用于处理数值型max,min,count可以处理任何类型
2.以上分组函数都忽略null值
3.count函数的一般使用count(*)用作统计行数
4.和分组函数一同查询的字段要求是group by后的字段
DQL-条件查询
使用WHERE 子句,将不满足条件的行过滤掉,WHERE 子句紧随 FROM 子句。
语法:select<结果> from<结果> where<结果>
比较
=, != 或<>, >, =, <=
逻辑运算:and 与 ;or 或 ;not 非
DQL-分组查询
语法:
select 分组函数,列(要求出现在group by的后面)
from 表
[where 筛选条件]
group by 分组的列表
[having 分组后的筛选]
[order by 子句]
外键:引用另外一个数据表的某条记录。
外键列类型与主键列类型保持一致
数据表之间的关联/引用关系是依靠具体的主键(primary key)和外键 (foreign key)建立起来的。
例:CONSTRAINT 约束名 foreign key(majorid ) references major(id)
多表设计_关联查询
1、当主表中没有对应的记录时,不能将记录添加到从表
2、不能更改主表中的值而导致从表中的记录孤立
3、从表存在与主表对应的记录,不能从主表中删除该行
4、删除主表前,先删从表