MySQL
修改历史: 2025-07-01 修复了sql语句的代码快无法高亮的问题 MySQL-基础 数据库管理系统DBMS MySQL数据模型 客户端->DBMS->多个数据库->多个二维表 SQL语句 DDL(Data Definition Language)数据定义语言(数据库、表、字段) DML(Data Manipulation Language)数据操作语言 DQL(Data Query Language)数据查询语言 DCL(Data Control Language)数据控制语言,管理数据库用户,控制数据库的访问权限 DDL-数据定义 数据库操作 大类 语句 作用 查询 show databases 查询所有数据库 select database() 查询当前数据库 创建 create database [if not exists] 数据库名 (如果不存在)创建一个数据库 使用 use 数据库名; 使用数据库 删除 drop database [if exists] 数据库名 删除数据库 表操作-查询 语句 作用 show tables; 查询当前数据库所有表 desc 表名; 查询表结构 show create table 表名; 查询指定表的建表语句 表操作-创建 12345create table 表名( 字段1 字段类型 [约束] [comment 字段1注释], …… 字段n 字段类型 [约束] [comment 字段1注释])[comment 表注释]; 关于约束: 约束 描述 关键字 非空约束 限制字段值不能为null not null 唯一约束 保证字段所有数据唯一 unique 主键约束 主键是一行数据的唯一标识,非空且唯一 primary key 默认约束 字段未指定值则用默认值 default 外键约束 让两张表的数据建立连接 foreign key 字段数据类型 数值 类型 大小(byte) 描述 tinyint 1 小整数值 smallint 2 大整数值 mediumint 3 大整数值 int 4 大整数值 bigint 8 极大整数值 float 4 单精度浮点数 double 8 双精度浮点数 decimal 小数值(精确定点数) 例如double,需使用double(整个数的长度,小数部分长度) 字符串 类型 描述 char 定长字符串 varchar 变长字符串 tinyblob 不超过255个字符的二进制数据 tinytext 短文本字符串 blob 二进制形式的长文本数据 text 长文本数据 midiumblob 二进制形式的中等长度文本数据 midiumtext 中等长度文本数据 longblob 二进制形式的极大文本数据 longtext 极大文本数据 日期时间 大小 范围 格式 描述 date 3 1000-01-01至9999-12-31 YYYY-MM-DD 日期值 time 3 -838:59:59至838:59:59 HH:MM:SS 时间值或持续时间 year 1 1901至2155 YYYY 年份值 datatime 8 1000-01-01 00:00:00至9999-12-31 23:59:59 YYYY-MM-DD HH:MM:SS 混合日期和时间值 timestamp 4 1970-01-01 00:00:01至2038-01-19 03:14:07 YYYY-MM-DD HH:MM:SS 混合日期和时间值,时间戳 修改、删除表结构 语言可以不掌握,但是要会图形化操作 DML-数据操作 添加数据: insert into 表名(字段1,字段2,……) values(值1,值2,……); 字符串应该和日期型数据应该包含在引号内 插入的数据大小,应该在字段的规定范围内 修改数据 update 表名 set 字段名1=值1,字段名2=值2,…[where 条件] 删除数据 delete from 表名 [where 条件] DQL-数据查询 基本查询: 基本查询 select 字段列表 from 表名; select * from 表名;(不建议在开发中使用这种方式,因为不直观) 起别名 select 字段 as ‘别名’ from 表名;as可省略 去重 select distinct 字段名称 from 表名; 条件查询: select 字段列表 from 表名...
JavaSE-Java8的两个重要特性
jdk8 新特性 函数式接口: 函数式接口是什么?如果接口中只声明有一个抽象方法,则此接口称为函数式接口(FunctionalInterface) 为什么要有函数式接口?因为只有给函数式接口创建对象时,才可以使用lambda表达式。 java8中声明的函数式接口所在包:java.util.function 4个基本的函数式接口:(直接copy宋的课件) 函数式接口 称谓 参数类型 用途 Consumer<T> 消费型接口 T 对类型为T的对象应用操作,包含方法: void accept(T t) Supplier<T> 供给型接口 无 返回类型为T的对象,包含方法:T get() Function<T, R> 函数型接口 T 对类型为T的对象应用操作,并返回结果。结果是R类型的对象。包含方法:R apply(T t) Predicate<T> 判断型接口 T 确定类型为T的对象是否满足某约束,并返回 boolean 值。包含方法:boolean test(T t) lambda表达式 lambda表达式怎么用? 语法规则: ->的左边:lambda的形参列表,参数的类型都可以省略。如果形参列表只有一个,则一对()也可以省略。 ->的右边:lambda体,只有一行执行语句时,则一对{}可以省略,如果有return,则也要省略。 写法举例 1Comparator<Integer> com = (o1 , o2) -> Integer.compara(o1,o2); lambda表达式的本质: 一方面,lambda表达式作为接口实现类的对象;另一方面,lambda表达式是匿名函数。 方法引用 方法引用可以看作是lambda表达式的进一步刻画。 当需要提供一个函数式接口的实例时,我们可以使用lambda表达式提供此实例。 当满足一定的条件是,我们还可以使用方法引用或构造器引用替换lambda表达式。 方法引用作为了函数式接口的实例。 格式: 对象 :: 实例方法 要求:函数式接口的抽象方法a与其内部实现时调用的对象的某个方法b的形参列表和返回值类型都相同。此时可以考虑使用方法b实现对a的替换、覆盖。 注意此方法b是非静态方法,需要对象调用。 类 :: 静态方法 要求:函数式接口的抽象方法a与其内部实现时调用的对象的某个静态方法b的形参列表和返回值类型都相同。此时可以考虑使用方法b实现对a的替换、覆盖。 注意此方法b是静态方法,需要类调用。 类 :: 实例方法 要求:函数式接口中的抽象方法a与其内部实现时调用的对象的某个方法b的形参列表和返回值类型都相同。同时,抽象方法a中有n个参数,方法b中有n-1个参数,且抽象方法a的第一个参数作为方法b的调用者,且抽象方法a的后n-1个参数与方法b的n-1个参数的类型相同(或一致)。 注意此方法b是非静态方法,需要对象调用。但是形式上,写出对象a所属的类。 构造器引用 格式:类名 :: new 调用了类名对应的类中某一个确定的构造器。具体调用的是类中的哪一个构造器,取决于函数式接口的抽象方法的形参列表。 数组引用 格式:数组名 :: new StreamAPI Stream使用的流程 实例化 一系列的中间操作 执行终止操作 实例化: 三种方法: 方法一:通过集合 例如:对于List结构,直接使用list.stream()就能创建stream实例 方法二:通过数组 类似方法一,使用Arrays的静态方法stream()Arrays.stream(arr) 方法三:streamof public static<T> Stream<T> of(T... values) : 返回一个流 例如: 12Stream<Integer> stream = Stream.of(1,2,3,4,5);stream.forEach(System.out::println); 中间操作: 筛选与切片 123456789101112131415@Testpublic void test1() { //创建Stream List<Employee> list = EmployeeData.empData(); Stream<Employee> stream = list.stream(); //filter(Predicate p) 过滤 stream.filter(e -> e.getAge() >...
JavaSE-File类与IO流
File类与IO流 File类的实例化 File类位于java.io包下,本章中涉及到的相关流也都声明在java.io包下。 File类的一个对象,对应于操作系统下的一个文件或文件目录(或文件夹) 123456 /*相对路径:相对于某一个文件目录来讲的相对位置。在IDEA中 * 在IDEA中,如果使用单元测试方法,相对路径是相对于当前的module * 如果使用main方法,相对路径是相对于当前的project * */ File file1 = new File("d:/io/test.txt");File file2 = new File("iotest"); 12345678//public File(String parent, String child)//参数1:一定是一个文件目录//参数2:文件目录或者是一个文件 File file1 = new File("d:/io", "test.txt"); //public File(File parent, String child)//参数1:一定是一个文件目录//参数2:文件目录或者是一个文件 File file2 = new File(file1,"file3.txt"); IO流 流(Stream)的分类: 流向不同:输入流、输出流 处理单位不同:字符流、字节流 角色不同:节点流、处理流 (抽象基类) 输入流 输出流 字节流 InputStream OutputStream 字符流 Reader Writer FIleReader、FileWriter: 步骤: 创建读写的File对象 创建输入流或输出流 具体读入或写出 读入:read(char[] cbuffer) 写出:write(String str)/write(char[] cbuffer,0,len) 关闭流资源,防止内存泄露 使用举例:复制hello.txt文件到hello_copy.txt 123456789101112131415161718192021222324252627282930313233@Testpublic void test2(){ FileReader fr = null; FileWriter fw = null; try { File file = new File("hello.txt"); File dest = new File("hello_copy.txt"); fr = new FileReader(file); fw = new FileWriter(dest); char[] cbuffer = new char[5]; int len;//记录每次读入字符个数 while ((len = fr.read(cbuffer)) != -1) { fw.write(cbuffer, 0, len); } } catch (IOException e) { e.printStackTrace(); } finally { //关闭流资源 try { if(fr != null) fr.close(); } catch (Exception e) { e.printStackTrace(); } try { if(fw != null) fw.close(); } catch (Exception e) { e.printStackTrace(); } ...
JavaSE-泛型
泛型 泛型在集合、比较器中的使用 1234567891011121314151617181920212223//泛型在List中的使用@Testpublic void test1(){ //举例:将学生成绩保存在ArrayList中 //标准写法: //ArrayList<Integer> list = new ArrayList<Integer>(); //jdk7的新特性:类型推断 ArrayList<Integer> list = new ArrayList<>(); list.add(56); //自动装箱 list.add(76); list.add(88); list.add(89); //当添加非Integer类型数据时,编译不通过 //list.add("Tom");//编译报错 Iterator<Integer> iterator = list.iterator(); while(iterator.hasNext()){ //不需要强转,直接可以获取添加时的元素的数据类型 Integer score = iterator.next(); System.out.println(score); }} 123456789101112131415161718192021222324252627282930313233343536//泛型在Map中的使用@Testpublic void test2(){ HashMap<String,Integer> map = new HashMap<>(); map.put("Tom",67); map.put("Jim",56); map.put("Rose",88); //编译不通过 // map.put(67,"Jack"); //遍历key集 Set<String> keySet = map.keySet(); for(String str:keySet){ System.out.println(str); } //遍历value集 Collection<Integer> values = map.values(); Iterator<Integer> iterator = values.iterator(); while(iterator.hasNext()){ Integer value = iterator.next(); System.out.println(value); } //遍历entry集 Set<Map.Entry<String, Integer>> entrySet = map.entrySet(); Iterator<Map.Entry<String, Integer>> iterator1 = entrySet.iterator(); while(iterator1.hasNext()){ Map.Entry<String, Integer> entry = iterator1.next(); String key = entry.getKey(); Integer value = entry.getValue(); System.out.println(key + ":" + value); }} 1234567891011121314151617181920class CircleComparator1 implements Comparator<Circle> { @Override public int compare(Circle o1, Circle o2) { //不再需要强制类型转换,代码更简洁 return Double.compare(o1.getRadius(),...
JavaSE-集合框架
集合框架 Java集合框架体系 java.util.Collection:存储一个一个的数据 子接口:List:存储有序、可重复的数据(“动态”数组) ArrayList(主要实现类)、LinkedList、Vector 子接口:Set:存储无序、不可重复的数据(中学数学中的集合) HashSet(主要实现类)、LinkedHashSet、TreeSet java.util.Map:存储一对一对的数据(key-value键值对,类似于中学数学的函数) HashMap(主要实现类)、LinkedHashMap、TreeMap、Hashtable、Properties Collection接口 常用方法 Collection中有15个常用的方法,其实现类可以使用 集合和数组的转换 集合–>数组toArray 数组–>集合调用Arrays的静态方法asList 向Collection中添加元素的要求:元素所属类一定要重写equals方法 因为Collection的相关方法(contains、remove)在使用时要调用equals方法 遍历 iterator迭代器: iterator迭代器常用来遍历集合元素 123while(iterator.hasNext()){ System.out.println(iterator.next());//next()指针下移,将下移以后的元素返回} (补充)增强for循环: 作用:遍历数组和集合 格式: 123for(要遍历的集合或数组的元素类型 临时变量 : 要遍历的集合或数组变量){ 操作临时变量输出} 说明: 针对于集合来讲,增强for循环底层仍使用的是迭代器 增强for循环执行的过程中,是将集合或数组中的元素依次赋值给临时变量,注意,循环体中对临时变量的修改,可能不会导致原有集合或数组元素的修改 List接口 常用方法 第一部分: Collection中声明的15个方法 第二部分:因为LIst是有序的,所以会增加一些索引方法 常用方法大致可分为:增、删、改、查、插、长度、遍历 方法声明 说明 add(Object ele) 添加ele元素 addAll(Collection eles) 将eles中的所有元素添加进来 remove(Object ele) 删除指定索引的元素,并返回此元素 remove(int index) 删除指定索引的元素,并返回此元素 set(int index , Object ele) 设置指定索引位置的元素为ele get(int index) 获取指定索引元素 add(int index , Object ele) 在指定索引插入ele元素 addAll(int index , Collection...
JavaSE-常用类与基础API
常用类与基础API String类的深入认识 类的声明 123public final class String implements java.io.Serializable, Comparable<String>, CharSequence, Constable, ConstantDesc 以上是java源码中对于String类的声明,我们可以注意到: final:String是不可继承的 Serializable:可序列化的接口。凡是实现此接口的类的对象就可以通过网络或本地流进行数据的传输 comparable:凡是实现此接口的类,其对象都可以比较大小 内部声明的属性 jdk8及之前:private final char value[];//存储字符串的容器 final:指明此value数组一旦初始化,其地址就不可变 jdk9开始,为节省内存空间做了优化:private final byte value[]//存储字符串的容器 字符串常量的存储位置 字符串常量都存储在字符串常量池(StringTable)中 字符串常量池不允许存储两个相同的常量 内存上,jdk7之前存放在方法区,jdk7之后存放在堆空间 String的不可变性 当对字符串进行重新赋值时,需要重新指定一个字符串常量的位置进行赋值,不能在原有的位置修改 当对现有的字符串进行拼接时,需要重新开辟空间以保存拼接以后的字符串,不能在原有位置修改 当调用字符串的replace()替换现有的某个字符时,需要重新开辟空间保存修改以后的字符串,不能在原有位置修改 String实例化的两种方式 第一种:String s1 = "hello" 第二种:String s2 = new String("hello") 连接符: 常量+常量,存储在字符串常量池,返回字面量的地址。注:此时的常量可能是字面量,也可能是final修饰的常量 常量+变量或者变量+变量,通过new创建一个新的字符串,返回堆空间中此字符串对象的地址 调用字符串的intern()返回的是字符串常量池中字面量的地址 concat():不管是常量还是变量,都返回一个新new的对象 String类构造器 12345678910111213// 无参构造(但实际无意义,因为 String 是不可变的)public String();// 通过字符串字面量构造(实际很少直接使用)public String(String original);// 通过字节数组构造(使用平台默认字符集解码)public String(byte[] bytes);// 通过字节数组构造(指定字符集解码)public String(byte[] bytes, String charsetName);// 通过字节数组的指定范围构造(offset 起始位置,length 长度)public String(byte[] bytes, int offset, int length);// 通过字符数组构造public String(char[] value);public String(char[] value, int offset, int count); Stirng类与常见的其它结构之间的转换 Stirng和基本数据类型之间的转换在包装类中已经写过,在此省略,详见 面向对象(高级)-包装类 String和char[]的转换 String–>char[]:调用toCharArray(),char[] arr = str.toCharArray() char[]–>String:调用String的构造器 String和byte[]的转换 编码:String–>byte[]:调用getBytes(),()内可以用"字符集名称"指明字符集,不写则使用默认字符集 关于字符集:utf-8中汉字占3个字节,一个字母使用1个字节;gbk中一个汉字占2个字节,一个字母占1个字节。两者都向下兼容ascii码。 解码:byte[]–>String:使用构造器,如果需要也要指定字符集 编码和解码指定字符集要相同,否则会乱码。 String常用的方法 String类包含有查找、截取、字符/字符数组、开头结尾、替换等常用API,内容很多且很啰嗦,建议在使用中学习,在此省略。 详细内容参见Java String 类 |...
JavaSE-多线程
多线程 概念 程序:为完成任务,用某种语言编写的一组指令的集合。 进程:程序的一次执行过程,或是正在内存中运行的应用程序。 线程:进程可以进一步细化为线程,是程序内部的一条执行路径。线程是CPU调度和执行的最小单位。 不同进程之间是不共享内存的。 进程之间的数据交换和通信的成本很高。 线程调度策略 分时调度:所有线程轮流使用CPU的使用权。并且平均分配每个线程占用CPU的时间 抢占式调度:让优先级高的线程以较大的概率优先使用CPU。如果线程的优先级相同,那么就会随机选一个。Java使用的是抢占式调度。 并行和并发: 并发是指一个处理器同时处理多个任务。 并行是指多个处理器或者是多核的处理器同时处理多个不同的任务 并发是逻辑上的同时发生(simultaneous),而并行是物理上的同时发生。 也就是说,只有多核CPU才能并行,单核CPU本身就不能同时处理多个进程,只能把一段时间拆成多块来分别执行不同的进程 多线程的优点 提供应用程序的响应。 提高计算机CPU的利用率。 改善程序结构。将既长又复杂的进程拆为多个线程,独立运行,便于理解和修改。 多线程创建方式 方式一:继承Thread类的方式 创建一个继承于Thread类的子类 重写Thread类的run() 创建当前Thread的子类对象 通过对象调用start() 创建线程代码: 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950public class ThreadTest { public static void main(String[] args) { //方式1:创建子类 MyThread myThread = new MyThread(); myThread.start(); MyThread2 myThread2 = new MyThread2(); myThread2.start(); //方式2:创建匿名子类 new Thread(){ @Override public void run() { for (int i = 0; i < 100; i++) { if(i%2==0){ System.out.println(Thread.currentThread().getName()+" "+i); } } } }.start(); new Thread(){ @Override public void run() { for (int i = 0; i < 100; i++) { if(i%2!=0){ System.out.println(Thread.currentThread().getName()+" "+i); } } } }.start(); }}class MyThread extends Thread{ @Override public void run() { for (int i = 0; i < 100; i++) { if(i%2==0){ System.out.println(Thread.currentThread().getName()+" "+i); } } }}class MyThread2 extends...
JavaSE-异常
异常 0.概述 异常是指程序在执行过程中出现的非正常情况,如果不处理最终会导致JVM的非正常停止 异常的抛出机制:Java把不同异常用不同的类表示,一旦发生某种异常,就创建该异常类型的对象,并且抛出(throw)。然后程序员可以捕获(catch)到这个异常现象,并处理;如果没有捕获这个异常对象,那么这个异常对象会导致程序的终止。 1.常见异常 Error:StackOverflowError、OOM Exception: 编译时异常(受检异常)在执行javac.exe时出现的异常: ClassNotFoundException FileNotFoundException IOException 运行时异常(非受检异常)在执行java.exe时出现的异常: ArrayIndexOutOfBoundsException NullPointerException ClassCastException NumberFormatException InputMismatchException ArithmeticException 2.异常处理 方式一:try-catch-finally 基本结构: 12345678910try{ ......//可能产生异常的代码}catch(异常类型1 e){ ......//当产生异常类型1时的处置措施}catch(异常类型2 e){ ......//当产生异常类型2时的处置措施}finally{ ......//无论是否异常都会执行} 使用细节: 如果写了多个catch,如果多个异常类型不存在子父类关系,则不同类型的catch谁写在上边,谁写在下边都可以;如果存在子父类关系,则子类异常要写在父类异常上面,否则会报错 catch中异常处理的方式: 自己编写输出的语句 printStackTrace():打印异常的详细信息 getMessage():获取发生异常的原因 try中声明的变量,出了try结构后就不可以再调用了 将一定要被执行的代码写在finally 无论try中或catch中是否存在仍未被处理的异常、无论try中或catch中是否存在return,都会执行。唯一的例外:System.exit(0)会强行终止当前运行的VM 在开发中,有一些资源(输入流、输出流、数据库连接、Sokect),在使用完后,必须显式地进行关闭,否则会导致内存泄漏。 方式二:throws+异常类型 格式:public void test() throws 异常类型1,异常类型2,.....{//可能存在编译时异常的代码} throws处理异常的方式,仅是将可能出现的异常抛给了此方法的调用者。调用者仍要考虑如何处理异常。 方法重写的要求:(针对编译时异常) **(重要)**子类抛出的异常类型要么和父类异常类型一样,要么是父类异常类型的子类。 throws和try-catch-finally的选择: 如果程序代码中,涉及到资源的调用(流、数据库连接、网络连接等),则必须考虑使用try-catch-finally来处理,保证不出现内存泄漏。 如果父类被重写的方法没有throws异常类型,则子类重写的方法中如果出现异常,只能考虑使用try-catch-finally进行处理,不能throws。 开发中,方法a中依次调用了方法b,c,d等方法,方法b,c,d之间是递进关系。此时,如果方法b,c,d中有异常,我们通常选择使用throws,而方法a中通常选择使用try-catch-finally。 3.抛出异常对象 异常的处理过程中有两个过程,一个是“抛”,一个是“抓“ “抛”的过程在程序上就是产生异常对象的过程,具体又可以分为自动抛和手动抛,这里的throw就是手动抛的过程 “抓”的过程实际上就是处理异常的过程,上述的throws和try-catch-finally就是处理异常的过程。 throw的使用:写在方法里,格式是throw 异常对象,这样就可以产生一个异常对象。 例子: 123456try{ throw new Exception("手动抛出异常");//创建一个名为手动抛出异常的异常对象}catch (Exception e) { System.out.println("捕获异常"); ...
面向对象(高级)
面向对象高级 static关键字 static用来修饰的结构:属性、方法;代码块、内部类 我们可以按照变量在类中声明的位置,分为局部变量和成员变量。对于成员变量又可以进一步分类: 对于加了static关键字的变量,我们称为静态变量、类变量; 对于没有加static关键字的变量,我们称为实例变量、非静态变量。 静态变量和实例变量对比 静态变量 实例变量 个数 只有一份,被类的多个对象共享 每一个对象都保存有一份 内存位置 jdk6及之前,在方法区,jdk7及之后再堆 存放在堆空间的对象实体中 生命周期 随类的加载而加载,随类的卸载而消亡 随对象的创建而加载,随对象的消亡儿消亡 调用者 可被类直接调用,也可被对象调用 只能被对象调用 static修饰方法 随着类的加载而加载 可以通过“类.静态方法”的方式,直接调用静态方法 静态方法内可以调用静态的属性或静态的方法,不可以调用非静态的结构(比如属性和方法) 静态方法可被类直接调用,也可被对象调用;实例方法只能被对象调用 静态方法内不能用this和super(理解:因为静态方法随类的加载而加载,而this和super都是需要产生对象才可以使用的,但是VM是先加载类再加载对象,所以静态方法使用this和super显然是不合适的) 什么时候要使用static? 属性:1)当前类的对象是否能共享此属性,且此变量值相同。2)常量 方法:方法内操作的变量都是静态变量。工具类的方法,如:Arrays、Maths 单例(Singleton)设计模式 饿汉式 1234567891011class Bank{ private Bank(){//1.私有化构造器 } //2.创建实例 //4.声明为static private static Bank instace = new Bank(); //3.获取实例 public static Bank getInstance(){ return instance; }} “立即加载”,随着类的加载就创建了 优点:写法简单,运行较快,是线程安全的 缺点:内存占用时间长 懒汉式 1234567891011121314class GirlFriend{ private Bank(){//1.私有化构造器 } //2.声明实例 //4.声明为static private static Bank instace =null; //3.获取实例,如果没有创建对象,则在方法内再创建 public static Bank getInstance(){ if(instance == null){ instance=new Bank(); } return instance; } } “延迟加载”,在需要的时候才创建对象 优点:节省内存 缺点:线程不安全 类的成员之四:代码块 代码块,也叫初始化块。是用来初始化类或对象的信息。按照是否加static修饰分为静态代码块和非静态代码块。静态代码块随着类的加载而执行,由于类的加载只会执行一次,所以静态代码块只会执行一次;非静态代码块随着对象的创建而执行,没创建一个实例,都会执行一次。静态代码块要先于非静态代码块执行。 作用:可以把不同构造器中相同的部分写在代码块中进行赋值;对静态变量进行赋值。 例子: 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354public class UserTest2 { public static void main(String[] args) { User2 user1 = new User2(); System.out.println(user1.getInfo()); System.out.println("===================================="); User2 user2 = new User2("KuoZ", "1234"); ...
面向对象(进阶)
面向对象(进阶) this关键字 this可以调用:属性、方法;构造器 this调用属性和方法 this 理解为当前对象,也就是说代表调用属性或方法的对象. this 通常可以省略,但是在属性的名称和形参变量的名称一样的情况下,就必须用this. 标示出成员变量。方法里通常省略this 。 this调用构造器 使用this(形参列表) 调用当前类中其它的重载的构造器,this(形参列表) 必须声明在当前构造器的首行,所以在一个构造器最多出现一次。 理解:在类中有n个构造器,则最多有n-1个this(形参列表) 结构 面向对象特征之二:继承性 继承的基本概念 继承性的好处: 减少代码冗余,提高复用性 便于功能扩展 产生了is-a的关系,为多态的使用提供了前提 继承性的特点 单继承性:但是一个子类只能有一个父类。 Java支持多层继承,一个父类可以扩展为多个子类。 Java中声明的类,如果没有显式声明其父类,默认继承于java.lang.Object类。 Java中子类父类的概念是相对的。 继承的格式 1234567class A{}class B extends A{} 上边代码中: A类:父类、superClass、超类、基类 B类:子类、subClass、派生类 继承的作用 通过这样声明,子类能够获得了父类声明的所有属性和方法。 子类继承父类后,还可以扩展自己的功能,要区别于集合和子集的概念。 同时,继承不打破封装性,所以因为封装性,子类不能直接调用父类私有的属性。但可以通过get方法调用。 方法的重写(overwrite/override) 子类对从父类继承过来的方法进行的覆盖、覆写的操作,称为重写(overwrite) 方法重写的规则: 父类被重写的方法的方法名和形参列表必须相同 子类重写的权限修饰符不小于父类的修饰符。特例:子类不能重写父类中private的方法 返回值类型: 父类为void,则子类重写只能是void 父类返回为基本数据类型,则子类同类型 父类返回为引用数据类型,则子类重写的方法的返回值类型相同 或 是引用数据类型的子类 关于异常类型,子类重写的方法抛出的异常类型可以和父类被重写的方法抛出的异常类型相同,也可以是其子类 super关键字 使用场景:在子类中已经对父类中的方法进行了重写,但是又想要调用父类的方法,这是就要用super关键字 子类与父类定义了同名的属性,使用super可以区分子类和父类的属性。 super可以调用属性、方法;构造器 super调用属性、方法 子类继承父类以后,可以在子类的方法或构造器中调用父类的属性和方法。在满足封装性的前提下,使用super. 表示父类的属性或方法。 一般情况下,我们可以考虑省略super. ,但是如果子类中声明了同名的属性或者重写了父类的方法,就必须用super. 表示父类的属性和方法。对于子类父类的属性要尽量避开重名的情况(编程规范),而方法可能无法避免,就可以用super. 来调用 super调用构造器 子类继承父类时是不会继承构造器的,可以在子类构造器中用super(形参列表) 调用父类的构造器。 规定super(形参列表) 必须写在子类构造器的首行,这也就意味着this和super只能出现一个。 如果没有写super(形参列表) 或this(形参列表) ,则默认是super() 。 由2、3得出结论,子类的任何一个构造器要么调用本类中重载的构造器,要么调用父类中的构造器。 由4得到,一个类中声明有n个构造器,最多有n-1个构造器使用了this(形参列表) ,剩下那一个一定使用super(形参列表) 。–>在调用子类的构造器时,一定直接或间接调用了父类的构造器,也正因为调用了父类的构造器,我们才会将父类中声明的方法或属性加载到内存中,供子类对象使用。 子类对象实例化的全过程: 从结果来看,体现为类的继承性。 从过程上来讲,当我们通过子类的构造器创建对象时,一定会直接或间接得调用到其父类的构造器,父类也会直接或间接调用其父类的构造器……直到调用了Object类的构造器为止。 面向对象特征之三:多态性 基本概念 多态性使用的前提:1.要用子类的继承关系 2.要有方法的重写 如何理解多态性? 广义上:子类对象的多态性、方法的重写 狭义上:主要指子类对象的多态性 Java中多态性主要体现在子类对象的多态性:子类的对象赋给父类的引用。 例Object obj = new String("hello");其中String()是子类的构造器,而Person是String的父类。 多态的优劣: 优点:1....