Java程序结构
- 注释
//单行注释 //凡是某一行“//”符号右边的文字都是注释 /*多行注释*/ //Java是用/**/进行多行注释 /**文件注释*/ //文件注释的规则与多行注释类似,它的语法是/**…*/。 /**通常在设计类或方法时,为了更详细地解说用途,可以使用文件注释。编写文件注释后,可以使用 javadoc.exe工具程序, 将此文件注释处理成Java API文件,所产生的文件是HTML文件 */
- 面向对象设计
Java是纯面向对象程序语言,所有的Java程序代码都是在类内,一个完整的Java程序至少需要有一个类
- 类区块
类区块是用左大括号“{”和右大括号“}”括起来,一个类区块内可以有其他方法(或称函数)区块
- 公有类
一个Java程序只能有一个公有类(public class),同时这个类的名称需与Java程序名称相同
- main()方法
每个独立的Java程序必须要有main()方法,这是Java程序执行的起点。设计main()方法时,必须是public static void类型,参数则是字符串数组“String[ ] args”(void代表方法没有返回值)
- IO交互
// 输入(input) import java.util.Scanner; Scanner 变量名 = new Scanner(System.in); 变量名.next数据类型(首字母大写); // 输出(output) System.out.println("内容") // 换行 System.out.print("内容") // 不换行
- 命令的结尾
Java程序内每条命令的结尾是分号“;”
数据类型
- 变量
//数据类型 变量1,变量2,变量n int age,count...
- 常量
/* 字面常量 数据类型 常量=值 */ int salary=3500; /* 具名常量 final 数据类型=值 */ final double PI=3.14;
- 基本数据类型
// 数值型 // 整数 - byte(1) - short(2) - int(4) - long(8) // 浮点数 - float(4) - double(8) // 字符 - char(2) // 非数值型 // 布尔 - boolean(1)
- 引用数据类型
- 类(class)
// 通过API:Application Programming Interface查看各种类信息 - class 1. Sting类:字符串 - 在java.lang包下,不需要import,不可变类型 - Java程序中双引号字符串,都是String类的对象 - String构造方法创建对象 String 变量 new String(参数) // 地址不同,每次新建地址 - String赋值创建 String 变量 = “abc” // 内容相同则地址相同 - 字符串的比较 ==比较的是地址 // s1==s2 equals(参数)方法比较的是值 // s1.equals(s2) - 字符串的长度 // 变量.length() - 字符串的索引 // 变量.charAt(元素番号) 2. String Builder - 内容是可变的,不会产生新的变量 StringBuilder sb = new StringBulider() sb.appen("abc") // 返回的是对象本身 public String toString() // 把StringBuilder转换成String public StringBuilder(String s) // 构造方法实现String转StringBuilder - reverse方法反转 return new StringBuilder(s).reverse().toString() 3. 集合ArrayList<E类型:泛型> - 提供一种存储空间可变的存储模型,存储的数据容量可以发生变化 - ArrayList的构造方法 public ArrayList() // 创建一个空的集合对象 ArrayList<String> array = new ArrayList<>() public boolean add(E e) // 将制定的元素追加到末尾 array.add("abc") public void add(int index, E e) // 在指定位置插入指定元素 - 其他方法 remove() get() set() size()
- 接口(interface)
- interface - 特点 - 就是一种公共的规范标准,通用接口 - java的接口更多的体现在对行为的抽象 - 接口用interface关键字修饰 public interface 接口名(){} - 类实现接口用implements表示 public class 类名 implements接口名(){} - 接口不能实例化,可参照多态方式通过实现类对象实例化,这叫接口多态 // 多态的形式 - 具体类多态,抽象类多态,接口多态 // 多态的前提 - 有继承或实现关系,有方法重写,有父(类或接口)引用指向(子或实现)类对象 // 接口的实现类 - 要么重写接口中的所有抽象方法 - 要么是抽象类 // 接口的成员特点: - 成员变量: - 只能是常量,默认修饰符public static final 变量 - 构造方法: - 接口没有构造方法,因为接口主要是对行为进行抽象的,是没有具体存在 - 一个类如果没有父类,默认继承自Object类 - 成员方法: - 只能是抽象方法,默认修饰符public abstract 方法名(){} // 类和接口的关系: - 类和类的关系 - 继承关系,只能单继承,但可以多层继承 - 类和接口的关系 - 实现关系,可以单实现,也可以多实现,还可以在继承一个类的同时实现多个接口 - 接口和接口的关系 - 继承关系,可以单继承,也可以多继承 // 抽象类和接口的区别: - 成员区别 - 抽象类 - 常量,变量,有构造方法,有抽象方法,也有非抽象方法 - 接口 - 常量,只有抽象方法 - 关系区别 - 类与类 - 继承,单继承 - 类与接口 - 实现,可以单实现,也可以多实现 - 接口与接口 - 继承,单继承,多继承 // 设计理念区别 - 抽象类 - 对类抽象,包括属性,行为 - 接口 - 对行为抽象,主要是行为
- 数组(array[ ])
- array[ ] - 定义数组 - 动态定义 // 数据类型 [ ] 数组名 = new 数据类型(3) int [ ] arr = new int [3] - 静态定义 // 数据类型 [ ] 数组名 = {元素1,元素2,n} int [ ] arr = {1,2,3} - 二维数组 // 数据类型 [ ] [ ] 数组名 - 遍历数组 // 遍历不到通常用-1表示 - for循环遍历 for(i=0,i<arr.length,i++) { 输出arr[i]} - foreach循环 for(int i:arr){ 输出i } - 常见错误 - 索引越界 - 超过length的长度 - 空指针 - 数据为null - 多个数组指向相同内存地址时,一变全变
- 数据类型的转换
自动类型转换:
变量1 = 变量2,变量2的范围小于变量1,可自动
变量1 = 变量2,变量2的范围大于变量1,报错强制类型转换:
目标变量 = (数据类型)源变量
运算符
- 单元运算符
只需要一个运算符就可以运算,这类运算符称为单元运算符
自增i++,先运算后加
自增++i,先加后运算
自减i--,先运算后减
自减--I,先减后运算 - 二元运算符
需要有两个运算符才可以运算的符号称为二元运算符
赋值运算符
变量1 = 变量2 // 变量2赋值给变量1
变量1 == 变量2 // 不是赋值是比较,判断变量2是否等于变量1算数运算符
加法(+) // 复合运算为:+=
减法(-) // 复合运算为:-=
乘法(*) // 复合运算为:*=
除法(/) // 取商,复合运算为:/=
求余(%) // 取余,复合运算为:%=比较运算符
大于(>)
小于(<)
大于等于(>=)
小于等于(<=)
等于(==)
不等于(!=) // !也叫反向运算符逻辑运算符
或(&) //a&b,a和b都false才false,否则true
// &&为短路或,a真则不看b
与(|) //a|b,a和b都true才true,否则false
// ||为短路与,b真才真
非(!) //!a,结果和a的结果正好相反
异或(^) //a^b,a和b结果不同则true,相同为false - 三元运算符
需要三个运算符进行运算,这类运算符称为三元运算符
表达式? X:Y //true则返回X,false则返回Y
例如:a>b? a:b
流程控制
- 顺序结构
从上到下,从左到右,顺序执行。比如:赋值语句
- 分支结构
根据条件表达式的返回值执行不同的分支。比如:if分支,switch分支
// if语句
// 单分支
if(关系表达式) {
语句体;
}
// 双分支
if(关系表达式){
真语句体;
} else {
假语句体;
}
// 多分支
if(关系表达式){
语句体1;
} else if{
语句体2;
} ...else {
语句体n+1;
}
// switch语句
switch (表达式){
case 值1:
语句体1;
break;
case 值2:
语句体2;
break;
default:
语句体n+1;
[break;]
}
// case穿透:如果case中没有break,会穿透下一个case语句
- 循环结构
// for循环
for(初始化语句;判断语句;控制语句){
循环体语句;
}
for(int i=1;i<=5;i++) {
System.out.println("test1");
}
for(;;){ //死循环
}
// while循环
while(条件判断){
循环体;
}
int j=1;
while(j<=5) {
System.out.println("test1");
j++;
}
while(true){ //死循环
}
// do while循环
do {
循环体;
} while(条件判断);
do{ //死循环
} while(true);
跳转控制语句
- continue
- 跳过本次循环
终止循环语句
- break
- 终止循环
Random
import java.util.Random;
Random 变量 = new Random();
变量n= 变量.nextInt(10) + 1 // 随机生成1-10
方法・函数
//定义方法
public static void 方法名([形参]) { // 形参:数据类型 变量,多个参数用,分隔 例如:int a, int b
方法体;
}
- 定义的方法与main方法同级
- 两个明确
- 参数
- 明确几个参数,明确参数的类型
- 返回值
- 明确返回值类型
### 调用方法
/*
方法名([实参]);
- 要在main方法中调用自定义方法
- 关键字参数要用:例如a:10,b:20
*/
### 返回值
return 数据 // 有返回值要定义同类型变量接收
public static 返回类型 方法名(形参) {}
- 方法的返回类型与return的返回类型相同
### 方法重载
- 在同一个类中方法名要相同,参数不同
- 参数个数不同
- 参数类型不同
### 注意事项
- 方法不能嵌套
- return的返回值和方法返回类型要相同
- 方法中的变量不会修改全局变量的值
- 对于引用类型的参数,形参的改变影响实参的值 // 比如:方法的参数是arr数组,方法修改arr
文件操作
-
File类
// 构造方法
File(String pathname)
File(String 路径,String 文件)
File(File 目录,String文件)
// 创建功能
- 创建文件
File f1 =new File(文件路径)
f1.createNewFile()
- 创建目录
File f2 =new File(目录)
f2.mkdir()
- 创建多层目录
File f3 =new File(多层目录)
f2.mkdirs()
// 成员方法
public boolean isDirectory() // 判断是否为目录
public boolean isFile() // 判断是否为文件
public boolean isExists() // 判断是否存在
public String getAbsolutePath() // 返回绝对路径
public String getPath() // 返回目录名
public String getName() // 返回文件或路径名
public String [ ] list() // 返回目录和文件名的数组
public File [ ] listFiles() // 返回目录和文件名的File对象数组
// 删除功能
public boolean delete() // 删除抽象路径名表示的文件或目录
-
IO流
- 字节流(binary)
- 抽象基类
FileInputStream // 输入流的所有类的超类
FileOutputStream // 输出流的所有类的超类
// 写数据
FileOutputStream(String name) // 创建文件输出流以指定的名称写入文件
FileOutputStream fso = new FileOutStream(文件名); // 追加写:在文件名后加,true
fso.write(内容信息);
fso.close();
- 3种方式
void write(int b) // 一次写一个字节
void write(byte[ ] b) // 一次写一个字节数组
getBytes() // 返回字符串对应的字节数组
void write(byte [ ] b, int off, int len) // 将len字节从指定的字节数组开始,从偏移量off开始一次写一个字节数组
// 读数据
FileInputStream(String name) // 从指定的名称读入文件
FileInputStream fso = new FileInputStream(文件名);
fso.read();
fso.close();
- 3种方式
void read(int b) // 一次读一个字节
void read(byte[ ] b) // 一次读一个字节数组
void read(byte [ ] b, int off, int len) // 将len字节从指定的字节数组开始,从偏移量off开始一次写一个字节数组
// 复制数据
FileInputStream f1 =new FileInputStream(文件名);
FileOutputStream f2 =new FileOutputStream(文件名);
byte [ ] bys = new byte[1024];
int len;
while((len=f1.read(bys))!= -1){
f2.write(bys, off=0, len);
}
f1.close();
f2.close();
-
字节缓冲流
// 字节缓冲输入流
BufferInputStream b1 = new BufferInputStream(new FileInputStream(文件名));
// 字节缓冲输出流
BufferOutputStream b1 = new BufferOutputStream(new FileOutputStream(文件名));
- 编码解码
- String s = "中国"
- 编码
- byte[ ] bys = s.getBytes(charsetName:"GBK");
- 解码
- String ss = new String(bys, charsetName:"GBK")
// 字符流(text)
- 抽象基类
InputStreamReader // 输入流的所有类的超类
OutputStreamWriter // 输出流的所有类的超类
// 写数据
- OutputStreamWriter(String name)
- 创建文件输出流以指定的名称写入文件
- FileOutputStream fso = new FileOutStream(文件名);
- 追加写:在文件名后加,true
- fso.write(内容信息);
- fso.close();
- 5种方式
- void write(int b)
- 写一个字符
- void write(char[ ] b)
- 写一个字符数组
- void write(char [ ] b, int off, int len)
- 写字符数组的一部分
- void write(String b)
- 写一个字符串
- void write(byte [ ] b, int off, int len)
- 写字符串的一部分
- 读数据
- FileInputStream(String name)
- 从指定的名称读入文件
- FileInputStream fso = new FileInputStream(文件名);
- fso.read();
- fso.close();
- 3种方式
- void read(int b)
- 一次读一个字节
- void read(byte[ ] b)
- 一次读一个字节数组
- void read(byte [ ] b, int off, int len)
- 将len字节从指定的字节数组开始,从偏移量off开始一次写一个字节数组
- 复制数据
- FileInputStream f1 =new FileInputStream(文件名);
- FileOutputStream f2 =new FileOutputStream(文件名);
- byte [ ] bys = new byte[1024];
- int len;
- while((len=f1.read(bys))!= -1){
f2.write(bys, off=0, len);
}
- f1.close();
- f2.close();
异常
体系:Throwable(所有异常的超类)
Error
- 硬件或系统级别的严重错误,java无法捕获
Exception
- RuntimeException
编译期是不检查的,出现问题后,在修改代码
运行时异常
- 非RuntimeException
编译期就必须处理的,否则程序不能通过编译
编译时异常
-
try...catch
try {
可能出错的代码;
catch (异常类名 变量名){ // 变量名:是一个对象,可以使用.方法
异常的处理代码;
}
}
### Throwable成员方法
public String getMessage() // 返回Throwable的详细消息字符串
public String toString() // 返回此可抛出的简短描述
public void printStackTrace() // 把异常的错误信息输出在控制台
### throws 异常类名;
- 跟在方法的括号()后面
- 主动抛出异常,谁调用谁处理该异常
### 自定义异常
public class 异常类名 extends Exception{
无参构造方法()
带参构造方法()
}
- 调用自定义异常时,要用throw new 自定义异常("提示信息")抛出异常,调用方法()后throws 异常
public void checkScore(int score) throws fException{
if (score<0 || score>120){
throw new fException("分数有误");
} else {
System.out.println("分数正常");
}
}
throw和throws的区别
- throw
- 用在方法体内,跟的是异常对象名
- 表示抛出异常,由方法体内的语句处理
- 执行throw一定抛出了某种异常
- throws
- 用在方法申明后面,跟的是异常类名
- 表示抛出异常,由方法的调用者来处理
- 表示出现异常的一种可能性,并不一定会发生
面向对象
类
- 类的特点
- 类是对象的数据类型
- 具有相同属性和方法的一组对象的集合
- 类是对现实生活中一类具有共同属性和行为的事物的抽象
- 类的定义
public class 类名 {
成员变量;
构造方法(无参/有参); // ALT+INSERT快捷键用于生产构造方法
成员方法;
get();
set();
}
- 成员变量
- 类中方法外的变量
- String brand;
- 成员方法
- 类中的方法,不加static
- public void 方法名() {}
- 方法中定义的变量叫局部变量
- 抽象类abstract
特点:
- 一个没有方法体的方法应该定义为抽象方法,而类中如果有抽象方法,该类必须定义为抽象类
public abstract class 类名(){
public abstract void 方法名();
}
//抽象类中不一定有抽象方法,有抽象方法的类一定是抽象类
//抽象类不能实例化
- 可以参照多态通过子类对象实例化,这叫抽象类多态
//抽象类的子类
- 要么重写抽象类中的所有抽象方法
- 要么是抽象类
//抽象类的成员特点:
- 成员变量:
- 可以是变量或常量
- 构造方法:
- 有构造方法但不能实例化,用于子类访问父类数据的初始化
- 成员方法:
- 可以有抽象方法,限定子类必须完成某些动作
- 也可以有非抽象方法,提高代码复用性
对象
- 对象的特点
属性
- 每个对象的每个属性都有特定的值
行为
- 对象能够执行的操作
- 对象是能摸得着看得到的真实存在的实体
- 创建对象
类名 对象名 = new 类名
Phone p = new Phone();
- 使用对象
使用成员变量
- 对象名.变量名
- p.brand
使用成员方法
- 对象名.方法名()
- p.call()
封装
- private关键字
- 用来保护私有变量不被外界随意修改
- get方法,给外界访问
- set方法,给外界修改
- 比如:private String name;
- this关键字
- 在成员方法用this.变量可以访问成员变量,否则为局部变量(形参)
- 代表所在类的对象引用
- 构造方法
// 用来创建对象,完成对象的初始化
public class Student {
public Student() { // 如果没有定义构造方法,系统会生成默认的
}
}
继承
- 继承的特点
可以使得子类具有父类相同的属性和方法,还可以在子类中重新定义,追加属性和方法
public class 子类名 extends 父类名()父类:基类或超类
子类:派生类优点:提供了代码的复用性,提供代码的维护性
缺点:类之间产生了关系,耦合性增加,子类的独立性降低
IS-A:是什么的一种,存在继承关系
子类不能同时继承多个类
想要多继承要依次多层传递继承
- LEGB原则:
- Local:局部作用域
- Enclosing:嵌套作用域
- Global:全局作用域
- Built-in:内置作用域
- this关键字:
可以访问本类中的成员变量和方法
- this.成员变量
- this(构造方法)
- this.成员方法
- super关键字:
可以访问父类中的成员变量和方法
- super.成员变量
- super(构造方法)
- super.成员方法
- 子类中的所有构造方法默认都会访问父类的无参构造方法
- 子类初始化之前,先完成父类的初始化
- 子类构造方法的第一条语句默认都是super()无参
- 如果父类中没有无参构造方法
- 通过super关键字取显示的调用父类的带参构造方法
- 或者在父类中定义一个无参的构造方法
- 方法重写
子类中出现了和父类中一模一样的方法申明
@Override
- 可以帮助检查重写方法的方法申明的正确性
父类的私有方法不能被重写
父类的私有成员子类是不能继承的
子类方法访问权限不能低于父类现有权限
public>默认>私有
修饰符
- 包Package
- java中的包可以看做就是文件夹,用于对类进行分类管理
- Package 包名;
- Package com.Animal;
- javac -d . 编译文件,会自动建包
- javac com.Animal 编译文件,手动建包
- 包里放class文件即编译文件
- 导包import
- import 包名.文件
- import com.Animal
- 权限修饰符
private
- 访问权限在同一个类中
默认
- 比private同一个包中子类无关类
protect
- 比默认多了不同包的子类
public
- 不同包的无关类,最大权限
- final修饰符
修饰方法:
- 表明是最终方法,不能被重写
修饰变量:
- 表明是常量,不能修改再次赋值
修饰类:
- 表明该类是最终类,不能被继承
修饰局部变量:
基本类型变量
- 基本类型的数据值不能发生改变
引用类型变量
- 引用类型的地址值不能发生改变,但地址里面的内容可以发生改变
- static修饰符
特点:
- 被类的所有对象共享
- 这也是判断是否使用static关键字的条件
- 也可以通过类名调用
- 类.变量
- 静态成员方法只能访问静态成员
多态
- 特点
- 同一个对象,在不同时刻表现出来的不同形态
- 成员变量:
编译看左边,执行看左边
- 成员方法:
编译看左边,执行看右边
因为成员方法有重写
- 优点:
提高了程序的扩展性
定义方法的时候,父类做参数,但使用子类参与操作
- 缺点:
不能使用子类的特有功能
可以使用转型解决此弊端
- 向上转型
从子到父:父类引用指向子类对象
Animal a = new Cat();
- 向下转型
从父到子:父类引用转为子类对象
Cat c = (Cat)a;
- 前提
- 有继承或实现关系
- 有方法重写override
- 有父类引用指向子类对象
Cat a = new Cat() // 猫是猫
Anaimal a = new Cat() // 猫是动物