Java
第一章Java概述
第一节 Java的特点
Java是一门面向对象编程语言,不仅吸收了C++语言的各种优点,还摒弃了C++里难以理解的多继承、指针等概 念,因此Java语言具有功能强大和简单易用两个特征。极好地实现了面向对象理论,允许程序员以优雅的思维方式 进行复杂的编程 。
Java具有简单性、面向对象、分布式、健壮性、安全性、跨平台与可移植性、多线程、动态性等特点。
单核心 单线程 多核心 多线程。(微秒级)
windows,mac,linux,unix .apk .ipa
面向对象三大特征 :封装,继承,多态
java面向对象: 封装,继承,多态,抽象,接口
cmd测试java代码的时候遇到了一个错误
可以用javac -encoding utf-8 文件名.java
如果有包名的话,要包名.类名才能运行
第二节 Java开发环境组成 (jdk)
1jvm虚拟机
JVM 是Java Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的 计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。
跨平台 任何软件的运行都需要运行在操作系统上,而我们使用Java编写的软件可以运行在任何的操作系统 上,这个特性成为java语言的跨平台性。这个特性是由JVM实现的,我们编写的程序运行在JVM上,而JVM运 行在操作系统上。
Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得 Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。
Windows OS MacOS Linux OS 不同的操作系统,内部的运行原理是不一样,换句话说,windows的软件不能在mac电脑上面进行安装。所 以我们很多软件的制作成本就加大了。例如 爱奇艺,需要制作windows版 还需要制作mac版。此时就需要两 个开发团队。假如你是老板,急需一种操作:能不能开发一个版本在不同的平台中都能运行,这就是跨平 台。
Java是支持跨平台操作的一门语言。
java程序的执行过程:源代码(.java)->编译->字节码(.class)->jvm解释->机器码->系统执行
jvm的作用:加载由源文件编译生成的字节码文件,将其转为机器码,发给系统执行
2 JRE Java运行环境(Java Runtime Environment,简称JRE)是一个软件,由SUN微系统所研发,JRE可以让计算机系 统运行Java应用程序(Java Application)。JRE的内部有一个Java虚拟机(Java Virtual Machine,JVM)以及一些 标准的类别函数库(Class Library)。
3 jdk JDK是 Java 语言的软件开发工具包,主要用于各种环境下的java程序开发,包括移动设备、嵌入式设备上的java应 用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。(电工的工具包 钳子,螺丝刀,欧姆表。。。 )jdk中自带有jre。
数据类型
声明:数据类型 变量名 = 初始值;
背住: 基本数据类型
四类八型:
整型 整数 byte(一个字节) short(2) int(4) long (8字节 要加l标记)
包装类 Byte Short
浮点型 小数 float(4 加f标记) double (8)
字符型 一个字符 char (单引号括起来的单个字符 2个字节 可以存储汉字)
布尔型 boolean (true/false)
引用数据类型: class 类 String字符串 数组,函数,对象 Enum枚举
字符类型
字符类型变量用于存储一个单一字符,Java中用char表示。
Java中,每个char类型的字符变量都会占用2个字节,16位。
char类型的变量赋值时,需要英文的单引号’’把字符括起来,如’a’。
char类型的变量赋值范围是0~65535内的整数。
char a = ‘中’;
面试题:char类型能存储汉字吗?
能,因为一个汉字是两个字节 任何字符在内存中都是以数字的形式存储的。 `package day823;
public class Demo1 {
public static void main(String[] args){
// 数据类型:
// 1. 基本类型
// 整数
// byte(1字节 -128 127) short(2字节 -32768 32767) int(4字节 -21亿 21亿) long(8字节)
// 小数(浮点数)
// float(4字节) double(8字节)
// 字符
// char(2字节 0-65535)
// 布尔
// boolean(1字节 true/false)
// 2. 引用类型
// 字符串
// String
// 类
// 数组
}
}
`
package day823;
public class Demo2 {
public static void main(String[] args) {
// 运算符
// 1. 算术运算符: 返回值是数值
// +,-,*,/,%,++,--
// 特殊规则: a. “+” 具有二义性:
// 1)如果操作数都是数值则做加法运算 2)如果操作数有字符串则做拼接
// b. ++,-- : 在具有多步操作的表达式中,放置的位置不同,则表达式结果不同
// c. /(除法): 与js不同,java中两个整数相除,结果还是整数
int num1 = 100;
int num2 = 200;
String num1 = "100";
int num2 = 200;
System.out.println(num1+num2);
int num1 = 10;
// 表达式只有一个自增/自减运算,此时++/--在前还是在后,结果没有影响
num1++;
++num1;
/System.out.println(num1);
//int num1 = 10;
// 这个表达式包含了两步运算: 1.自增 2.赋值 ,此时++在前和在后就有区别
//int num2 = num1++; // ++在后,先做其它运算,最后再++
//int num2 = ++num1; // ++在前,先做++,再做其它运算
//System.out.println(num1+" "+num2);
//int num1 = 10;
// 下面的表达式有两步操作:1.输出 2.自减
// 先做其它操作,再进行自减
//System.out.println(num1--);
//System.out.println(num1);
// 10 9
// int num1 = 10;
// int num2 = 3;
// System.out.println(num1+num2);
// System.out.println(num1-num2);
// System.out.println(num1*num2);
// System.out.println(num1/num2); // 整数相除还是整数 10/3 = 3
// System.out.println(num1%num2);
// 2. 关系运算符:>,>=,<,<=,==,!= : 返回值是boolean值(true/false)
// 特殊规则: ==(等于判断): 针对基本类型的数据,等号可以直接判断相等性
// 针对引用类型的数据,等号不能判断相等性
// int num1 = 10;
// int num2 = 14;
// System.out.println(num1>num2);
// System.out.println(num1>=num2);
// System.out.println(num1<num2);
// System.out.println(num1<=num2);
// System.out.println(num1==num2);
// System.out.println(num1!=num2);
// 3. 逻辑运算符: &&(逻辑与) ||(逻辑或) !(逻辑非) 返回boolean值
// 作用: 用于连接多个关系运算,进行多条件的判断
// && : 连接的条件全部成立,结果才为true 否则为false
// || : 连接的条件有一个成立,结果为true 否则为false
// ! : 对条件结果取反。结果为true 逻辑非之后为false
// int num1 = 10;
// int num2 = 3;
// System.out.println(num1>num2 && 1>5);
// System.out.println(num1>num2 || 1>5);
// System.out.println(!(num1>num2));
// 4. 赋值运算符: =(赋值), 增强赋值: +=,-=,*=,/=,%=
// int num1 = 10;
// int num2 = 20;
// num1 *= num2;
// System.out.println(num1+" "+num2);
// 5. 条件运算符(三目运算符): 条件表达式?结果1:结果2 返回结果数据
// 规则: 表达式结果为true 则返回结果1
// 表达式结果为false 则返回结果2
// int money = 101;
// String res = money>100?"富豪":"穷人";
// System.out.println(res);
// 6. 运算符的优先级:
// ()》++ ,-- , !》 算术运算符 (* / +-) 》关系运算符 》逻辑运算符(&& ||) 》赋值运算符 》条件运算符
boolean res = 3+5>6-20&&5*4-20<8+9||45/3!=21&&12-9+3*4>18&&!(4-5>1);
// 8> -14 && 0<17 || 15!=21 && 15 >18 && true
// true && true || true && false && true
// true || false && true
// true || false
// true
System.out.println(res);
}
}
package day823;
public class Demo3 {
public static void main(String[] args) {
// java 数据类型转换 : 现阶段针对数值类型之间的转换(byte,short,int,long,float,double,char)
// 为什么要类型转换:因为java存储数据的变量是限定了类型的,在程序处理数据的时候,
// 难免要进行变量数据的转存,此时就会产生类型转换的问题
// 数据类型转换:
// 1.隐式转换(自动)
// 规则: 当小范围的数据存储到大范围的类型中时,会发生自动转换
// 特点: 系统自动完成,不需要特别处理
// a. 定义两个不同范围的变量,将小范围数据存储到大范围的变量中
byte b = 10;
int i = 20;
// 小范围->大范围 : 自动转换
i = b; // 将byte数据存储到int中,此时发生自动转换
//System.out.println(b+" "+i);
// b. 两个不同类型的数值数据,进行运算
short s = 20;
int n = 50;
//short+int => int : 小范围的数据和大范围进行运算,小范围的数据自动向大范围数据对齐,做自动转换
//short x = s+n; // 报错
int xs = s+n;
System.out.println(xs);
int x = 10;
float y = 3.0F;
double j=3.0;
float res = x/y; // int和float进行运算,int数据自动转为float,再进行运算
System.out.println(res);
double reg=x/j;
System.out.println(reg);
// 2.显示转换(强制)
// 规则: 当将大范围的数据存储到小范围的类型中时,要进行强制转换
// 特点: 需要使用强制转换的语法完成转换
}
}
package day823;
public class Demo4 {
public static void main(String[] args) {
// java 数据类型转换 : 现阶段针对数值类型之间的转换(byte,short,int,long,float,double,char)
// 为什么要类型转换:因为java存储数据的变量是限定了类型的,在程序处理数据的时候,
// 难免要进行变量数据的转存,此时就会产生类型转换的问题
// 数据类型转换:
// 1.隐式转换(自动)
// 规则: 当小范围的数据存储到大范围的类型中时,会发生自动转换
// 特点: 系统自动完成,不需要特别处理
// 2.显示转换(强制)
// 规则: 当将大范围的数据存储到小范围的类型中时,要进行强制转换
// 特点: 需要使用强制转换的语法完成转换
// 强制转换的语法: 目标类型 变量名 = (目标类型)数据
// a. 定义两个不同类型的数值变量,将大范围的数据存储到小范围的变量中
// a1. 大范围类型的数据在小范围数据中能存储下,此时进行强转,结果没有损失
//byte b = 10;
//int n = 30;
// 大范围数存储到小范围变量中,需要使用强制转换才能完成处理
//b = (byte)n;
//System.out.println(b);
// a2. 整形数据之间,大范围类型的数据在小范围数据中存储不下,此时会导致【数据溢出】
byte b = 10;
int n = 129;
b = (byte)n; // n的值超出了byte的范围,强制转换后,byte中的值发生了溢出
System.out.println(b);
// 扩展: 请自己研究为什么129存储到byte中变成了-127
每一组都是-127
// a3. 浮点型数据和整形数据进行强制转换后,会发生【丢失精度】的问题
//int n = 10;
//double d = 2.34343;
//n = (int)d; // 将小数存储到int中,强制转换之后,只剩下整数部分,小数部分丢失
//System.out.println(n);
// a4. 整数和字符数据的强制转换,如果整数值在char(0-65535)的范围内,则会转成对应字符内容,超出范围返回不识别的内容
int n = 100;
char c = 'b';
//n = c; // 小范围存储到大范围,自动转换,直接存储对应字符的数值
c = (char)n; // 将4字节的整数,存储到2字节的字符中,此时要做强制转换
System.out.println(c);
}
}
Scanner
// package: 包声明。用于表示当前类的位置
package day823;
// import: 导入。 用于导入特定包下的类
// 使用其它包中的类时,必须先导入,才能使用
import java.util.Scanner;
//导包的潜规则: java.lang 下的类jvm会在运行时自动导入,不需要写import语句
public class Demo5 {
public static void main(String[] args) {
// Scanner: 扫描。键盘扫描器/控制台扫描器/输入工具类
// 作用: 能够接收键盘在控制台的输入内容,并可以把接收的内容存储到变量中
// System类是在java.lang包下的类,jvm会自动导入
System.out.println("=======程序开始==========");
// Scanner是在java.util包的下的类,使用的时候需要手动导入
// 使用new的方式,创建输入工具类对象
Scanner xx = new Scanner(System.in);
// 使用输入类对象的next()方法[等待]接收控制台的输入
//xx.next(); // next():可以等待接收控制台输入字符串内容
String res = xx.next(); //接收控制台输入的内容,并存储到字符串变量中
System.out.println("接收到输入的内容是:"+res);
System.out.println("=======程序结束=======");
}
}
String类的format()方法用于创建格式化的字符串以及连接多个字符串对象。熟悉C语言的同学应该记得C语言的sprintf()方法,两者有类似之处。format()方法有两种重载形式。
format(String format, Object… args) 新字符串使用本地语言环境,制定字符串格式和参数生成格式化的新字符串。
format(Locale locale, String format, Object… args) 使用指定的语言环境,制定字符串格式和参数生成格式化的字符串。
显示不同转换符实现不同数据类型到字符串的转换,如图所示。
转 换 符
说 明
示 例
%s
字符串类型
"mingrisoft"
%c
字符类型
'm'
%b
布尔类型
true
%d
整数类型(十进制)
99
%x
整数类型(十六进制)
FF
%o
整数类型(八进制)
77
%f
浮点类型
99.99
%a
十六进制浮点类型
FF.35AE
%e
指数类型
9.38e+5
%g
通用浮点类型(f和e类型中较短的)
%h
散列码
%%
百分比类型
%
%n
换行符
%tx
日期与时间类型(x代表不同的日期与时间转换符
第二章 Java流程控制
分支结构
- if(){}
- if(){}else{}
- if(){}else if(){}else if(){} else{}
switch(表达式){// byte short char int string
case 值1 break;
case 值 break;
每一个case 不能重复
default 找不到case 执行的默认语句
break 执行后跳出switch 语句 没有break则找到匹配的case后会把后面所有的语句都执行
}
- do while循环
while 先判断再执行
do while 先执行一次再判断 do while至少会执行一次
第三章 类与对象基础
面向对象程序设计(英语:Object-oriented programming,缩写:OOP)是种具有对象概念的程序编程典范,同 时也是一种程序开发的抽象方针。
在面向对象定义之中,也规定了一些基本的特征:
(1)封装:保护内部的操作不被破坏; 安全性
(2)继承:在原本的基础之上继续进行扩充; 复用性
(3)多态:在一个指定的范围之内进行概念的转换。可扩展性
对于面向对象的开发来讲也分为三个过程: OOA(面向对象分析)、OOD(面向对象设计)、OOP(面向对象编程)。
类的概念
什么是类
类是对具有相同属性的对象的一种抽象,它一般包括了属性和方法两大部分。可以理解为对象的设计图纸(房屋设 计图,手机设计图)。
总结:面向对象最终的目的是在保证功能实现的基础上,方便后期程序的维护。
类具有的内容
属性:成员属性/成员变量
方法: 成员方法
类的定义
public class 类名{ 属性 方法 }
构造方法小结:
定义构造方法:public + 类名(参数列表){初始化代码}
当类没有构造方法时,系统会给一个默认的空构造方法
当你一旦定义了自己的构造方法,系统就收回了默认的构造方法
如果还想用默认的构造方法,则必须自己另外定义 自定义的构造方法主要用于对象的初始化
第四章 重载 访问修饰符、静态、常用类
第一节:方法重载
为什么需要方法重载?
在一个类中可以有很多的方法,并且每一个方法都有自己的功能,但是方法太多,对开发者不友好,名字太多不好 记,所以使用方法重载,控制每一个方法中传入的参数,并且方法的名字都一样,java,会自动的根据传入参数的不 同,调用参数相对应的方法。此时开发者不需要再记各种方法的名字了。非常nice !
什么是方法重载?
经典面试题: 在一个类中可以有很多个相同名字的方法,并且这些方法中参数列表不同(参数个数不同,顺序不同,类型不同), 这就是方法重载。
顺序不同 ,也是重载的。
特点: 1. 函数/方法名相同
- 参数列表不同(参数个数不同,顺序不同,参数类型不同)。 如果方法名相同,参数列表也相同,此时虚拟机,不能分辨到底调用哪一个方法。 注意:方法重载不考虑返回值。
第二节:包和访问修饰符
为什么需要包?
a:没有包类多的时候不好找,所以包的作用在于管理类。包在磁盘体现上就是文件夹。
b:不同包下的类可以重名(同一目录类不能重名)
c:可以通过包做一些限定
2)包的定义语句:package 包名;
3)跨包请求的时候需要导入包:import 包名.类名;导入指定类import 包名.*;
//属于 java.lang 包下边得内容 每一个类都会自动的引入java.lang 包 System.out.println(); String int boolean … 2. 权限修饰符 public 公共的 主要修饰成员变量和方法 作用:权限的设置,保护属性不被外界侵犯。
权限 同一包 同一类 不同包的子类 所有类
public 允许 允许 允许 允许
protected/保护的 允许 允许 允许 不允许
默认 允许 允许 不允许 不允许
private 允许 不允许 不允许 不允许
子类无法使用父类私有的属性和方法.
protected 不同包的类不能访问.
一般属性用private修饰
- public : 类前面加上public修饰
作用: 被public修饰的类,在其它任何包,任何类中都可以被访问
- 默认(): 类前面不加访问修饰符
作用: 默认修饰的类,只能被本包中的类访问,在其它包的类中不能访问
- public(公有的访问修饰)
被public修饰的属性和方法,在任何包,任何类可以被访问
- protected(在类继承的过程中限定访问范围,学完继承再讲)
- 默认(什么都不写就是默认访问修饰)
同包下的类,自己类的内部可以正常访问
不同包下的类,无法访问
- private(私有的访问修饰)
只能被同类内的方法访问。同包下的类和其他包的类都不能访问
第三节:static
关键词 static
静态的 用来修饰属性(成员变量),则该属性就成为类属性,所有该类的实例都共用这一个属性,任何一个实例改变了属 性值,大家看到的都是修改过的值。在内存中static属性是所有类实例共有的内存地址。
用来修饰方法,则该方法是静态方法,静态方法只能访问静态属性(变量),不能访问一般的成员变量。
静态的属性和方法都可以通过类名加"."直接访问。
静态块:在类加载时自动调用 一般方法既可以访问一般属性(变量),也可以访问静态属性(变量)
public class Student {
String name;
int age;
static String className;
static double classMoney;
static {
System.out.println("这是静态块,加载就可以自动执行");
}
public void intro() {
System.out.println("我是"+name+",今年"+age+"岁了,我在"+
className+"班,有"+classMoney+"班费");
}
public static void showClassInfo() {
System.out.println(className+"班有"+classMoney+"元班费");
//age 和name不能访问了
}
public void buy(double money) {
classMoney-=money;
}
}
- 使用static修饰的属性,称为静态属性(类属性)
静态属性直接描述类的特征,不依赖于对象而存在
静态属性直接通过类名访问,也可以通过对象访问(不建议这样做),能够被所有对象共享。
静态属性在内存里只有一份,存储在类的方法区,被所有实例共享。而实例属性存在在堆区,每个属性都有自己独立的空间。
- 使用static修饰的方法,称为静态方法(类方法)
- 静态方法表示类的行为,不依赖于对象而存在
- 静态方法可以直接通过类名来访问,也可以通过对象访问(不建议这样做)。
- 静态方法中只能访问静态属性。静态方法不能访问实例属性。
静态方法中只能访问静态方法。静态方法不能访问其他实例方法。
实例方法中可以访问实例属性,也可以访问静态属性。
实例方法中可以访问其他实例实例方法。也可以访问其他静态方法。
第四节:String
基本数据类型 :不属于Object类型的继承体系之下
引用数据类型 :属于对象类型 Object类型的继承体系之下。
String 字符串 引用数据类型 Object
什么是String 字符串 , 引用类型。 字符串对象。
String的特点: 字符串不可变 每一个字符串都是String类的实例对象 正是因为字符串是不可变的,所以字符串是共享的。
字符串的效果上相当于一个char[] 数组,但是它的底层原理是byte[] 字节数组。
创建字符串的2种常用方法
最常用的直接创建 String str = “ABC”;
注意:直接使用双引号的就是字符串对象。虽然没有new
通过构造方法创建 String str = new String(“abc”);
split:按照指定规则将字符串拆分成数组
subString(begin,engin):获取两个索引之间的子串
replace(“要替换的子串”,”替换成的子串”)
方法名 含义
public int length(){} 获取字符串中字符的个数,拿到字符串长度
public String concat(String str){} 将当前字符串与参数字符串拼接,得到一个新的字符串
public char charAt(int index){} 返回指定索引位置的单个字符(索引从0开始)
public int indexOf(String str){} 查找参数字符串在本字符串中首次出现的索引位置,如果没有 则返回-1
public String substring(int index){} 截取从参数位置一直到字符串末尾。返回新的字符串
public String substring(int begin ,int end){} 截取从开始索引到结束索引之间的字符串。返回新的字符串, 前闭后开
public boolean endsWith(String str){} 判断字符串是否以指定的字符串结尾
public boolean startsWith(String str){} 判断字符串是否以指定的字符串开头
public String trim(){} 清楚左右两端的空格,并返回清除空格后的字符串
replace(oldStr,newStr){} 将所有出现的老字符串替换成新的字符串,并返回结果字符 串。
public String[] split(String regex){} 按照参数的规则将字符串拆分成若干部分,返回一个数组。 s
小结: 栈中存变量,new的对象存在堆中。
常量保存在常量池中。 String str1 = “abc”; 先去常量池中找”abc“ 是否存在,如果存在直接引用,不存在,就创建。
String str2 = “abc”;先去常量池中找”abc“ 是否存在,如果存在直接引用,不存在,就创建。
== :用法
- 如果是基本数据类型:== 比较值。
- 如果是引用数据类型:== 比较引用的地址
第五节:StringBuilder和StringBuffer
在java中字符串就是常量。就算对一个字符串进行操作,原来的字符串还是不会改变,只不过又生成了新的字符 串。 我们做的对字符串的任何操作,都不会改变原有字符串,但是会创建新的字符串对象
StringBuilder 是一个可变的字符序列。此类提供一个与 StringBuffer 兼容的 API,但不保证同步。该类被设计 用作 StringBuffer 的一个简易替换,用在字符串缓冲区被单个线程使用的时候(这种情况很普遍)。如果可能, 建议优先采用该类,因为在大多数实现中,它比 StringBuffer 要快。
数组也是对象
Java 实体类的基本格式
1私有属性2set/get3空构造,有参构造
4重写Object tostring方法 extend继承
第六节:日期及格式化
第五章 java 数组
第一节:数组
什么是数组 所谓数组,是有序的元素序列。 若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组 的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编 号称为下标。
js数组:1.没有数据类型限制,2.可以随意扩容。
Java中的数组 就是 将相同数据类型的数据 进行存储的数据格式。并且存储到数组中的数据都会自动生成一个 编号,称之为索引值或者下标。然后数组是通过操作索引值对数据进行存取。索引值从0开始。并且java中的 数组是定容,统一数据类型的。
特点:
- java数组是一种引用数据类型
- java数组中的数据类型必须统一
- java数组是定长的
- 数组的重新赋值,只能通过标准格式,不能使用简化格式赋值
- 初始化数组时如果没有直接赋值,那么数组中元素的默认值 整数类型:0 浮点型:0.0 字符型:“\u000” 布尔型:false 引用类型:null
- 因为数组是定长的,如果想扩容只能创建一个新的数组。 我们以后肯定会有很多地方要用到不定长的数组。用 List Map Set 集合框架
数组的异常 : ArrayIndexOutOfBoundsException 数组的下标越界异常。
NullPointerException 空指针异常 (说明数组是一个空的不能取值)
第六章 封装和继承
1 什么是封装
封装,即隐藏对象的属性和实现细节,仅对外公开接口(方法/函数),控制在程序中属性的读和修改的访问级 别;将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体,也就是将数据与操作数据的源代码进行有 机的结合,形成“类”,其中属性数据和函数都是类的成员。 封装的目的:是增强安全性和简化编程,使用者不必了解具体的实现细节,而只是要通过外部接口,以特定的访问 权限来使用类的成员。
1.2 java中的封装
广义来说:一切公共代码的抽取都可以叫封装。 一般体现在公共方法的封装。工具类。
狭义来说:隐藏对象的属性和实现细节。
1. 将属性私有化 ,使用private关键字修饰。
2. 为使用private关键字修饰的属性添加 get和set方法。通过get和set方法来操作属性。
2.1 什么是继承
继承是面向对象软件技术当中的一个概念,与多态、封装共为面向对象的三个基本特征。继承可以使得子类具有父 类的属性和方法或者重新定义、追加属性和方法等。
继承(英语:inheritance)。这种技术使得复用以前的代码非常容易,能够大大缩短开发周期,降低开发费用。 继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类的属性和方法,或子类从父类继承方法,使 得子类具有父类相同的行为。
如果某类B“继承”另某类A,就把这个B称为“A的子类或派生类(subclass)”,而把类A称为“B的父类”也可以称为“A 是B的超类或基类(superclass)”。
2.2 为什么需要继承
提升代码的可重用性
子类通过继承可以得到父类有的内容
能够扩展功能
通过继承子类可以扩展父类已有的功能
方便维护
多个子类都继承了父类的某个功能,当功能需要修改时,只要修改父类的这个功能即可
使用面向对象思想编程的时候,需要考虑的两个方面:
1.功能实现了没有?
2.后期维护方便吗?
2.3 继承的语法格式 java语言是单继承的
继承的语句格式:
2.4 方法重写 @Override注解
什么是方法重写
在Java和其他一些高级面向对象的编程语言中,子类可继承父类中的方法,而不需要重新编写相同的方法。 但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。方法重写 又称方法覆盖。
方法重写方法重载的区别:
重载(overload):发生在同一个类中 , 方法名相同,参数列表不同,不考虑返回值。
重写(override):发生在父子类中,子类继承父类的方法,方法名相同,参数也相同,但是实现方法体不同。
重写的注意事项
必须保证父子类中重写的方法,方法名相同,参数列表相同。
子类方法的返回值必须等于父类方法的返回值范围。
子类方法的权限必须要大于等于父类方法的权限(不包括 private)。
私有的不能被继承
toString()方法
任何类都是Object类的直接子类或者间接子类,在Object类中有一个toString()方法。当输出一个对象时,先调 用当前类的toString()方法,如果当前类没有toString() ,就去找当前类的父类,看是否有toString()方法,如果 过父类也没有,就去找Object类中的toString()方法并运行。
数据模型类 以后写类都要有:成员属性私有化,成员方法,构造方法,get/set方法 ,toString()
2.5 super关键字,this关键字
作用:如果子类既想使用自己的方法,又想使用父类的成员变量和成员方法,需要通过super关键字。
super 关键字的用法:
- 在子类的成员方法中访问父类的成员变量和成员方法。2. 在子类的构造方法中访问父类的构造方法。
2.6 继承中构造方法的特点(父子类)
特点 :
儿子有:5000000元 住海景洋房 构造方法不能被继承(构造方法是一个类独有的方法)
创建子类对象一定是先调用父类构造,再调用子类构造。(并且只有子类构造才能调用父类构造)。
子类构造可以通过super关键字调用父类有参构造 无参super() 有参super(参数列表) 。
super父类构造调用,必须是子类构造中的第一行语句。(并且一个子类构造,只能调用一次super())。必须先 有父再有子。
继承的特点: java中类与类之间是单继承的。但是可以多级继承。一个父类可以有多个子类。
2.7 Object类
Object是所有类的父类,任何类都默认继承Object
理论上Object类是所有类的父类,即直接或间接的继承java.lang.Object类。由于所有的类都继承在Object类,因 此省略了extends Object关键字。 该类中主要有以下方法: toString(),getClass(),equals(),clone(),finalize(), 其中 toString(),getClass(),equals()是其中最重要的方法。
注意:
Object类中的getClass(),notify(),notifyAll(),wait()等方法被定义为final类型,因此不能重写。 equals()方法 在比较字符串时 比较的是俩个字符串的值。但是实际上equals方法比较的是地址值。 为什么String就可以用equals()比较值呢?
因为String类中重写了equals()方法,所以可以比较值。
小结
- 继承关键字:extends
- 单继承,一个类只能有一个直接父类
- 子类可以继承父类:public protected 同包默认的属性和方法,不能继承private私有方法
- 子类可以书写自己的属性和方法
- 子类可以重写父类的方法
- 在子类中可以通过super调用父类的方法和属性。super.方法名/属性名
- 无父无子: a. 父类构造不能继承,但是必须调用 b. new子类的时候,子类构造的第一行必须调用父类的构造方法 c.如果子类不写super(),系统默认调用父类无参构造 d.可以通过super(参数)调用有参,并且必须第一行,并且只能有一个super()。
- 如果通过子类调用方法,优先调用自己的方法。子类重写方法之后调用自己的方法,如果子类没有重写方法 则使用父类的方法。 先子类—》再父类—》再父类–》。。。。–》Object
- 所有类都直接或者间接的继承了Object类。Object是所有类的基类,超类。 继承的作用: A. 减少代码冗余 B. 书
写一个父类,子类可以对父类进行扩展 C. 子类可以对父类重新定义
第三节 final关键字
final 代表最终的,不可改变的。 字符串为什么是不可变的?因为String类是用final关键字修饰的。
三种用法:
可以用来修饰类
final修饰的类不能被继承,也就意味着这个类其中的方法不能被重写。
可以用来修饰方法
final关键字修饰的方法不能被覆盖重写。表示一个最终的方法。
可以用来修饰变量
final修饰成员变量—》常量 命名必须全大写 一般多个单词使用下划线连接D_AGE,CAT_AGE 基本数据类型:使用final修饰的基本数据类型值不能变,并且只能被赋值一次。
引用数据类型:使用final修饰的引用类型,引用的地址值不能改变,但是值可以改变。
对于成员变量来说,使用final 修饰照样是不可变的,但是因为成员变量有默认值,所以必须手动赋值。
对final修饰的成员变量来说,可以直接赋值,也可以通过构造方法赋值,但是必须二选一。
如果要通过构造方法赋值,并且类中有多个构造方法,必须保证每一个构造方法都要对final修饰的成员 变量赋值。
第四节:基本类型包装类
4.1 概念 基本数据类型使用非常方便,但是我们没有对应的方法去操作它们,可以通过一个类把基本数据类型包装起来,在 类中定义一些方法,这个类就叫包装类。我们可以使用包装类中定义的方法去操作基本数据。
基本数据类型和对应的包装类:
byte Byte
short Short
int Integer
long Long
float Float
double Double
char Character
boolean Boolean
4.2 自动装箱与自动拆箱
装箱 基本数据类型转换成包装类
拆箱 包装类转换成基本数据类型
4.3 基本数据类型与字符串之间的转换
基本类型(数字)----》字符串(String)
- 可以使用数字直接+空字符串 例如: String a = 5 + “”;
- 使用Integer包装类的方法 toString(int i); 例如: String a = Integer.toString(100);
- 使用String类的方法valueOf(int i) 例如:String a = String.valueOf(100); 字符串----》基本数据类型(数字) 注意:只有数字类型的字符串,才可以转换成数字 使用包装类的方法xxx.parseXXX(“5”); NumberFormatException 数字格式异常
第七章 多态,抽象类和接口
1 程序中的多态
什么是多态
多态(Polymorphism)按字面的意思就是“多种状态”。在面向对象语言中,接口的多种不同的实现方式即为多 态。引用Charlie Calverts对多态的描述——多态性是允许你将父对象设置成为一个或更多的他的子对象相等的技 术,赋值之后,父对象就可以根据当前赋值给它的子对象的特性以不同的方式运作(摘自“Delphi4 编程技术内 幕”)。简单的说,就是一句话:允许将子类类型赋值给父类类型。
多态的前提是继承和方法重写。
多态:父类对象表现多种子类的形态的能⼒的特征,⼀句话多态就是⽗类引⽤⼦类对象。 向同⼀个⽗类的不同⼦类 发送同⼀条消息,⾏为不同。
对于父类中的一个方法,在不同子类中有不同的实现。父类引用子类对象,调用父类被重写的方法时,子类有不同 的响应。
程序设计中为什么使用多态: 实现程序设计的开-闭原则,对扩展开放,对修改关闭
1.2 如何实现多态 步骤:
1.继承:子类继承父类
2.重写:子类方法重写父类方法
3.向上转型:父类引用指向子类对象
4.调用父类被重写的方法时,不同的子类效果不同
1.3 向上转型 向下转型
向上转型:⽗类引⽤⼦类对象(⾃动成⽴,缺点是失去调⽤⼦类独有⽅法的能⼒)
向下转型:⼦类引⽤⽗类对象(强制转换,慎重)
第二节 抽象类
抽象类:如果一个类只是一个概念,没有具体的形象,我们可以把这个类定义为抽象类 抽象类的关键字abstract 抽 象类的使用场景:一般作为顶层类(父类),被子类继承
抽象方法和抽象类的格式 抽象类的存在不是为了创建对象,是为了让子类继承用的。
抽象类:使用abstract关键字修饰的类。
抽象方法: 使用abstract关键字修饰的方法 注意:抽象方法没有方法体,也没有{}
抽象类的特点:
1.抽象类不能创建对象,不能new对象
2.抽象类可以定义抽象方法,也可以没有抽象方法
3.有抽象方法 的类一定要定义成抽象类
4.抽象类中可以定义实例方法
5.抽象类可以定义构造方法,在子类中可以调用抽象类的构 造方法
6.子类继承了抽象类,则一定要重写/实现其中的抽象方法,如果没有实现父类的抽象方法,则子类也要变成 抽象类
7.抽象方法需要在方法前写abstract关键字,并且不能有方法体(不能写大括号)
第三节 接口
接口:一种标准、规范。对行为(方法)的抽象;一系列抽象方法的集合;
公共的规范,大家都要遵从这个规范使用。定制规则,展现多态。
接口和抽象类的地位等同,作为顶级存在(父类)
接口关键字:interface
实现接口:implements
实现接口意味着拥有了接口所表示的能力
1.接口中的方法不能直接使用,必须有一个实现类来实现接口
2.接口的实现类必须(覆盖重写)实现 接口中所有的抽象方法
3.创建实现类的对象,进行方法的调用。
注意:如果实现类没有覆盖重写接口中的方法,那么这个实现类自己就必须是抽象类。
接口中可以包含的内容
常量 (不可变的)
接口中的常量使用public static final 三个关键字修饰。
直接使用 接口名.常量名
接口可以多实现。一个类可以实现多个接口。
抽象方法
注意事项: 接口中的抽象方法必须是两个固定的关键字修饰 public abstract 这两个关键字可以省略不写。
接口的特点:
1、接口不能实例化,不能有构造方法
2、接口中的方法都是抽象方法
3、接口中的成员变量默认都是public static final修饰的
4、子类实现接口必须实现接口中的所有方法
5、多实现:一个类可以实现多个接口
6、接口可以继承接口:A extends B
第五节 面向对象的三大特征
异常
编译时异常:可以预测的,检查异常,需要进行强制的异常处理或者抛出。
运行时异常:在运行过程中发生的异常,不作强制处理要求。非检查异常。
InputMismatchException(输入不匹配异常) ArithmeticException(数学运算异常) ArrayIndexOutOfBoundsException(数组下标越界异常) NullPointerException(空指针异常)
NumberFormatException(数据转换格式错误)
try:监视、catch:捕获、finally:最终、throw:抛出、throws:声明
try…catch…finally 应用场景:存在必须执行的代码(释放资源的代码) finally块中的代码:一定会执行,并且会在return之前运行。
常见异常
算术异常类:ArithmeticExecption
空指针异常类:NullPointerException
类型强制转换异常:ClassCastException
数组负下标异常:NegativeArrayException
数组下标越界异常:ArrayIndexOutOfBoundsException
违背安全原则异常:SecturityException
文件已结束异常:EOFException
文件未找到异常:FileNotFoundException
字符串转换为数字异常:NumberFormatException
操作数据库异常:SQLException
输入输出异常:IOException
方法未找到异常:NoSuchMethodException java.lang.AbstractMethodError
抽象方法错误。当应用试图调用抽象方法时抛出。
java.lang.AssertionError 断言错。用来指示一个断言失败的情况。 java.lang.ClassCircularityError 类循环依赖错误。在初始化一个类时,若检测到类之间循环依赖则抛出该异常。 java.lang.ClassFormatError 类格式错误。当Java虚拟机试图从一个文件中读取Java类,而检测到该文件的内容不符合类的有效格式时抛出。 java.lang.Error 错误。是所有错误的基类,用于标识严重的程序运行问题。这些问题通常描述一些不应被应用程序捕获的反常情 况。 java.lang.ExceptionInInitializerError 初始化程序错误。当执行一个类的静态初始化程序的过程中,发生了异常时抛出。静态初始化程序是指直接包含于 类中的static语句段。 java.lang.IllegalAccessError 违法访问错误。当一个应用试图访问、修改某个类的域(Field)或者调用其方法,但是又违反域或方法的可见性声 明,则抛出该异常。 java.lang.IncompatibleClassChangeError
集合collection
第一节 集合和数组
Java集合框架(Java Collections Framework,JCF)是为表示和操作集合,而规定的一种统一的标准的体系结构。 [1] 任何集合框架都包含三大块内容:对外的接口、接口的实现和对集合运算的算法。
返回类型 方法名称 描述
boolean add(Object o) 在集合末尾添加元素
int size() 返回集合列表中元素个数
boolean removeAll(Collection col) 删除集合中的所有元素
boolean contians(Object o) 判断集合中是否存在指定的元素
boolean remove(Object o) 从集合中删除元素
viod clear() 清除集合中的所有元素
Iterator iterator() 为Iterator接口实例化
第二节 list接口特点
特点:有序、允许重复 有序集合(也称为序列 )。
用户可以通过整数索引(列表中的位置)访问元素,并搜索列表中的元素。
与set集合不同,列表通常允许重复的元素
ArrayList类
特点:动态数组;优势:随机查询(可以直接按索引访问)
实现了 List 接口 ArrayList本质上还是数组:对数组做了封装。
查找快,插入删除慢(因为会引起其他元素位置改变)
自动扩容(我们只管存取即可 如果长度不够 底层会自动的扩容)
可以存储所有元素(对象类型 或者说是Object的子类 )
可以存储null
存储的数据是有序的 ( 取出的顺序就是存储的顺序 )
多线程不安全(非线程安全)
数据可以重复
遍历方法 普通for循环遍历
增强for循环遍历
迭代器遍历
迭代器:又称游标 是程序设计的软件的软件设计模式,可在容器对象(container,链表或数组)上遍历的接口,
//3.迭代器遍历
Iterator it = list1.iterator();
//判断有没有下一个
while (it.hasNext()){
//取出相应的数据
Object next = it.next();
System.out.println(next);
}
第三节 set接口
3.1 Set接口
可以存储任意对象类型的数据 包括null。
无序(存储时的顺序跟遍历时的顺序不一定一样)
数据不能重复(自动去重)
数据结构跟List不同,没有下标
查找慢,插入删除快。(插入和删除不会引起元素位置改变。红黑二叉树)
根据equals()方法判断是否相等,hashcode()判断存储位置
3.2 HashSet 实现类
此类实现 Set 接口,由哈希表(实际为 HashMap 实例)支持
线程不同步
Set避免对象重复的规则:
- 如果对象的hashCode值不同,则不用判断equals方法,就直接存到HashSet中。
- 如果对象的hashCode值相同,需要用equals方法进行比较,如果结果为true,则视为相同元素,不存,如果 结果为false,视为不同元素,进行存储。
- 注意:如果对象元素要存储到HashSet中,必须覆盖hashCode方法和equals方法。才能保证从对象中的内容的角 度保证唯一。
迭代器 iterator
HashSet类中没有提供根据集合索引获取索引对应的值的⽅法,
因此遍历HashSet时需要使⽤Iterator迭代器。Iterator的主要⽅法如下
返回类型 方法 描述
boolean hasNext() 如果元素可迭代
Object next() 返回迭代的下一个元素
3.4.TreeSet
实现原理:TreeSet 基于 TreeMap 实现,需要实现比较器
基本数据类型 按照默认的排序 。和String类中重写了compareTo()方法定义了字符排序的规则。
默认按照元素的自然顺序进行排序,必须实现Comparable接口
有序
无重复
添加、删除元素、判断元素是否存在,效率比较高
TreeSet:可以对Set集合中的元素进行排序,是线程不安全的。
文件与IO数据流
方法、常量 l类型 描述
public File (String filename) 构造方法 创建File类对象并传输完整路径
public boolean createNewFlie() 方法 创建新文件
public boolean delete() 方法 删除文件
public boolean exists() 方法 判断文件的是否存在
public boolean isDirectory() 方法 判断给定的路径是否为目录
public long length() 方法 返回文件的大小
public String[] list() 方法 列出指定目录的全部内容,只列出名称
public File[] listFiles() 方法 列出指定目录的全部File对象
public boolean mkdir() 方法 创建目录
public boolean renameTo(File dest) 方法 为已有的文件重命名
流的分类
根据
方向分类 :输入流和输出流
内容分类:字节流和字符流
功能 处理流和字节流
1.输入字节流 抽象类:InputStream
程序可以从中连续读取字节的对象称为字节输入流
实现类:FileInputStream
方法 描述
public void close() 关闭输入流
public abstract int read() 以数字的方式读取内容
public int read(byte[] b) 将内容读到byte数组中,同时返回读入的个数
2.输出字节流 抽象类:OutputStream
程序可以向其中连续写入字节的对象称为字节输出流
实现类:FileOutputStream
方法 描述
public void close() 关闭输出流
public abstract void write(int b) 在数据流中写入一个字节
public void write(byte[] b,int off,int len) 在数据流中写入一个指定范围的byte数组
public void write(byte[] b) 在数据流中写入一个byte数组
public void flush() 刷新缓冲区
InputStream 字节输入