特点
- 比较简单
- 跨平台
- 多线程
- 高性能
环境类别
JDK
集成开发环境 包含 JVM JAR
JVM
虚拟机
JAR
软件包 类似 python 的库
第一个程序
public class HelloWord {public static void main(String[] args) {System.out.println("hello word");// 用于开发调试 在日志框中输出调试信息
}
}
CMD 命令行运行程序
1. 编译 用以下命名编译上面 hello word 文件 -encoding utf-8
这个的作用编码程序的时候使用 utf- 8 编码 防止出现 HelloWord.java:3: 错误: 编码 GBK 的不可映射字符 编译后的文件后缀是.class
javac -encoding utf-8 HelloWord.java
格式:
javac -encoding utf-8 文件路径
2. 运行 不要带 .class
文件后缀名
java HelloWord
输出结果
hello word
格式:
java 文件路径(不要带 .class 文件后缀名)
程序运行机制
解释型
代码翻译成电脑能看懂的语言运行 下次运行还要重复以上过程
例子: python 脚本翻译 c 语言运行
编译型
代码翻译成电脑能看懂的语言运行 下次运行可以直接运行编译后文件
例子: java 文件编译成.class 的文件 运行
区别
解释型:方便修改 执行时间长
编译型:执行时间短 不方便修改
语法
注释
// 单行注释
/*
多
行
注
释
*/
标识符
- 函数名 变量名 类名都叫标识符
- 变量名 不能以数字特殊符号命令
- 分大小写
- 不建议用中文
语言类型
强类语言
变量的使用符合规范 变量定义完才能使用
弱列语言
变量的使用可以不符合规范 变量可以不用定义完才能使用
语言区别
强类安全性高 速度比较慢 弱类反之
数据类型
类型
- 基本类型
- 引用类型
变量
String str = "str";
语法
数据类型 变量名 = "值";
八大数据基本类型
整数
int i1 = 100;// 常用
byte i2 = 100;
short i3 = 100;
long i4 = 100L;// 数字很大加大写 l 表示 long 类型
浮点数(小数)
float num1 = 44.1F;// 尾部加大写 f 表示 float 类型
double num2 = 1.1111;
字符
char str1 = '字';//char 和单引号都表示一个字符
String str2 = "字符串";//String 不是关键字是类 String 和双引号都表示是字符串
类型转换
强制转换(高到低)
int i = 128;
byte numbar= (byte)i;
格式:
数据类型 变量名 = (强制转换类型)被强制转换值;
正常转换(低到高)
int i = 128;
double n = i;
格式:
数据类型 变量名 = 被转换值;
注意
- 不能转换布尔值
- 不能转换不相干的对象
- 高转低 要制转换
- 转换可能会导致 精度 内容溢出 问题
命令规范
- 驼峰原则 如:“moduleType”
- 字母大写原则 如:“Module,Type”
- 类名使用 首字母大写原则和驼峰原则 如:”ModuleType”
- 方法名 变量名 使用驼峰原则 如:“moduleType”
- 常量名 字母或单词大写 多个单词用 下划线“_”区分开 如:“MODULE_TYPE”
变量 常量 作用域
变量
定义:储存对象的空间
int i = 100;
语法:
数据类型 变量名 = 值;
常量
定义:程序开始运行就不能被修改的变量
final int I = 100;
语法:
final 数据类型 变量名 = 值;
- 变量名 全部用大写 好区分
作用域
作用:让出命名空间
public class Demo {public static void main(String[] args) {
String s = "str";
newFunction();
System.out.println(s);
}
public static void newFunction(){String s = "str1";}
}
扩展
public class Demo {
// 类属性 初不始化都可以 归属于类
static double d = 2500;// 可以静态化属性
int i;
String s;
public static void main(String[] args) {
// 局部变量 必须要声明和初始化
// 实例化对象
Demo demo = new Demo();
// 不是静态属性的要实例类才能使用
System.out.println(demo.i);// 数字类型声明的属性没有初始化 默认值是 0
System.out.println(demo.s);// 字符串类型声明的属性没有初始化 默认值是 null
System.out.println(d);// 不用实例化类在使用 可以直接使用
}
}
运算符
算术运算符
public class Demo {public static void main(String[] args) {
int a = 2;
int b = 1;
// 加
System.out.println(a+b);
// 减
System.out.println(a-b);
// 乘
System.out.println(a*b);
// 除
System.out.println(b/(double)a);// 两个 int 类型数据消除 强制转为 double 类型正常显示
long l = 100L;
int i = 100;
int i1 = 100;
System.out.println(l+i);// 数据运算中 有 long 类型在里面运算 结果就是 long 类型
System.out.println(i+i1);
}
}
关系运算符
特点:结果返回布尔值
public class Demo {public static void main(String[] args) {
int a = 2;
int b = 1;
int c = 20;
int d = 22;
// 大于
System.out.println(a> b);
// 小于
System.out.println(a < b);
// 等于
System.out.println(a == b);
// 取余
System.out.println(c%d);
}
}
自增 自减 幂运算
public class Demo {public static void main(String[] args) {
int a = 4;
int b = a++;//a = a + 1 先赋值 在自增
System.out.println(a);
int c = ++a; // 先自增 在赋值
System.out.println(c);
//-- 同理
// 幂运算 2^3 2*2*2 = 8
double d = Math.pow(2,3);
System.out.println(d);
}
}
逻辑运算符
符号 | 含义 |
---|---|
&& | 两个结果为 true 结果才为 true |
|| | 两个结果 其中一个结果为 true 结果为 true |
!(a &&b) | 结果为 true 最终结果为 false 结果为 false 最终结果为 true |
public class Demo {public static void main(String[] args) {
boolean a = true;
boolean b = false;
System.out.println(a && b);// 与
System.out.println(a || b);// 或
System.out.println(!(a &&b));// 非
// 截止运算
int c = 5;
System.out.println(((c < 4)&&(c++ < 5)));// 已经提前知道结果 就不用后面的操作了
}
}
位运算(了解)
条件运算符
public class Demo {public static void main(String[] args) {
boolean b = false;
int i1 = 1;
int i2 = 0;
System.out.println(b ? i1 : i2); // 如果 b 结果为 true 结果为 i1 否则为 i2
}
}
扩展
- 优先级 用圆括号 括起来
public class Demo {public static void main(String[] args) {
int a = 1;
int b = 1;
System.out.println(a += b);//a = a+b
System.out.println(a -= b);//a = a-b
// 字符串连接符 +
System.out.println("" + a +b);// 字符串在前面会直接拼接
System.out.println(a + b + "");// 字符串在后面会先运算(执行设定操作)在拼接
}
}
包机制
- 方便管理
- 结构清晰
- 让出命名空间
- 域名倒置作为包名
定义包
语法:
package 包名;
导包
语法:
import 包路径. 类名;
导入所有:
import 包路径.*;
Java Doc(文档)
// 类注释
/**
* @author suchenqaq
* @version 1
* @since 1.8
*/
public class Doc {
String name;
// 方法注释
/**
*
* @param name
* @return
* @throws Exception
*/
public String test(String name) throws Exception{return name;}
}
属性 | 含义 |
---|---|
@author | 作者 |
@version | 文档版本 |
@since | 需要在 JDK 版本运行 |
@param | 什么方法参数名 |
@return | 什么返回值 |
@throws | 什么异常 |
生成文档
- 使用 CMD 命令 生成
javadoc -encoding utf-8 -charset utf-8 文件路径
参数 | 含义 |
---|---|
-encoding | 编译时候的编码 |
-charset | 文档编码 |
用户交互(Scanner)
next()
import java.util.Scanner;
public class Demo {public static void main(String[] args) {
// 创建对象 System.in 代表输入
Scanner scanner = new Scanner(System.in);
System.out.println("输入内容:");
// 判断用户有没有输入数据
if (scanner.hasNext()){
// 有就接收输入的数据
String userStr = scanner.next();
System.out.println("输入的内容为:" + userStr);
}
// 关闭 io 流
scanner.close();}
}
nextLine()
public class Demo {public static void main(String[] args) {
// 创建对象 System.in 代表输入
Scanner scanner = new Scanner(System.in);
System.out.println("输入内容:");
// 判断用户有没有输入数据
if (scanner.hasNextLine()){
// 有就接收输入的数据
String userStr = scanner.nextLine();
System.out.println("输入的内容为:" + userStr);
}
// 关闭 io 流 不关会一直占用资源
scanner.close();}
}
总结
nextLine() | next() |
---|---|
一定要输入到有效字符才结束 | 可以得完整的输入的字符串 |
输入有效字符串如果有空白 而且是第一个就是空白 会把空白去除掉 有效字符串后面还有空白 会把有效字符串后面的第一个空白的后面字符串去除掉 空白也是 |
顺序结构
- java 是顺序结构的 从上到下一条条的执行的
示例
public class Demo {public static void main(String[] args) {System.out.println(1);
System.out.println(2);
System.out.println(3);
System.out.println(4);
System.out.println(5);
}
}
选择结构
if 单选择结构
public class Demo {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);
String userStr = scanner.nextLine();
if (userStr.equals("ture")){System.out.println(userStr);
}
scanner.close();}
}
语法:
if(布尔表达式){// 等于 true 执行的代码}
函数 | 作用 |
---|---|
equals() | 判断字符串是否相等 |
if 双选择结构
public class Demo {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);
int userStr = scanner.nextInt();
if (userStr> 60){System.out.println("大于 60");
}else{System.out.println("小于 60");
}
scanner.close();}
}
语法:
if(布尔表达式){// 等于 true 执行的代码}else{// 等于 false 执行的代码}
if 多选择结构
public class Demo {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);
int userI = scanner.nextInt();
if (userI> 80){System.out.println("大于 80");
} else if (userI> 60) {System.out.println("大于 60");
} else{System.out.println("小于 60");
}
scanner.close();}
}
语法:
if(布尔表达式){// 等于 true 执行的代码}else if{// 等于 true 执行的代码}else{// 以上判断都等于 false 执行的代码}
Switch 选择结构
public class Demo {public static void main(String[] args) {Scanner scanner = new Scanner(System.in);
String userStr = scanner.nextLine();
switch(userStr){
case "A":
System.out.println('A');
break;
case "B":
System.out.println('B');
break;
case "C":
System.out.println('C');
break;
default:
System.out.println("什么都不是");
break;
}
scanner.close();}
}
语法:
switch("判断值"){
case "被判断值":
//ture 时执行代码
break;
default:// 可选
// 所有判断等于 false 时执行代码
break;
}
- 被判断值支持用字符串 JDK7 开始支持
- 本质用哈希值来比较的
循环
while
- 结果为 false 会一直循环 结果等于 true 才会停止
- 布尔表达式和执行代码 都处于同一作用域
import java.util.Scanner;
public class Demo {public static void main(String[] args) {
int i = 0;
while (i<100){
i++;
System.out.println(i);
}
}
}
语法:
while(布尔表达式){// 执行代码}
死循环
while(true){// 执行代码}
do .... while
- 先执行一遍代码 在循环
- 布尔表达式和执行代码 都处于同一作用域
import java.util.Scanner;
public class Demo {public static void main(String[] args) {
int i = 0;
do{
i++;
System.out.println(i);
}
while (i<100);
}
}
语法:
do{// 执行代码}while(布尔表达式)
for
- 初始化 布尔表达式 初始化的迭代代码和执行代码 都处于同一作用域
public class Demo {public static void main(String[] args) {for (int i = 0; i < 100; i++) {System.out.println(i);
}
}
}
语法:
for(初始化; 布尔表达式; 初始化的迭代代码){// 执行代码}
死循环
for(;;){// 执行代码}
增强型 for
语法:
for(key:value){// 执行代码}
遍历数组:
import java.util.Scanner;
public class Demo {public static void main(String[] args) {
// 数组
int[] iList= {1,2,3,4,5};
// 遍历数组
for (int x:iList){System.out.println(x);
}
}
}
Break 和 Continue 关键字
Break
作用:强制退出循环
public class Demo {public static void main(String[] args) {
int i = 0;
while(i<100){
i++;
System.out.println(i);
if (i == 50){
// 退出循环
break;
}
}
}
}
Continue
作用:用于在完整循环中 直接跳过符合条件的一个循环
public class Demo {public static void main(String[] args) {
int i = 0;
while(i<100){
i++;
if (i%10 == 0){
// 跳过等于这个条件的循环 直接执行下一条循环
// 被 10 除整数的余数(小数)等于 0 符合条件跳过此次循环
continue;
}
System.out.println(i);
}
}
}
CMD 传入参数
public class Demo {public static void main(String[] args) {for (String value:args){System.out.println(value);
}
}
}
1. 编译
javac Demo.java
2. 运行
- 参数以空格为间隔 数据容器类型为数组 数据类型 可以自己自定义
java Demo 第一个参数 第二个参数
3. 结果
第一个参数
第二个参数
递归
定义:自己调用自己
数组
定义:储存数据的容器
- 每个数据的名字类型叫下标 名字是数字 从 0 开始 最后的位数 是数据有多少位的位数
创建
声明语法:
数据类型[] 数组名;// 推荐使用这个方法声明
数据类型 数组名[];
基本使用
定义数组的宽度:
// 定义一个有数据类型的数组 可以存放 10 个定义的数据类型的数据
数据类型[] 数组名 = new 数据类型[10];
使用有宽度的数组:
public class Demo {public static void main(String[] args) {
// 定于一个 int 类型的数组可以存放 10 个 int 类型的数据
int[] list = new int[2];
// 添加数据
list[0] = 1;
list[1] = 2;
// 遍历数组 第一行种方式 取值
for (int key:list){System.out.println(key);
}
// 遍历数组 第二种方式 取键和值
for (int i = 0; i < list.length; i++) {System.out.println(list[i]);
}
// 取单独值
System.out.println(list[1]);
}
}
获取数组的长度:
数组名.length;
常见错误
ArrayIndexOutOfBoundsException
意思是调用数组中 不存在的下标(值)
初始化方式
public class Demo {public static void main(String[] args) {
// 静态初始化 创建和赋值 创建并进行赋值
int[] listNo1 = {1,2,3,4};
// 动态初始化 创建默认初始化 默认数据是 0
int[] listNo2 = new int[2];
}
}
- 数组创建后数据位数不可改变
内存分析
栈:可以为理解为一个名单 存放的变量 数组的名字
堆:可以理解为一个柜子 柜子上面有名字 柜子里存变量 和 数组 的数据
使用过程:用生成的名单 的名字查找 柜子上找到对应名字的柜子 然后取出里面数据使用 再次使用柜子的时候 之前的名单会自动销毁 然后在生成新的名单 重复上面的过程
多维数组
定义:数组里包含其他数组 理论可以一直包含无限的数组
语法:
// 动态数组
数据类型 数组名[][] = new 数据类型[1][2]
// 精态数组
数据类型[][] 数组名 = {{},{}}
public class Demo {public static void main(String[] args) {// new int 后的 [] 的位数决定每一层中的每个数组 能放下多少数据
int[][] listNo1 = new int[1][2];
listNo1[0][1] = 1;
System.out.println(listNo1[0][1]);
// int 后 [] 的位数多少就决定数组要嵌套多层数组
int[][] listNo2 = {{1,2,3,4},{1,2,3,4}};
System.out.println(listNo2[1][1]);
}
}
Array 类的使用
public class Demo {public static void main(String[] args) {int[] list = {1,2,3,4};
// 以字符串形式输出数组
System.out.println(Arrays.toString(list));
}
}
冒泡和稀疏数组
方法
定义:可以理解为一个实现解决的问题办法或制作工具
语法含义和结构:
修饰符(方法调用范围)加载方式 返回类型 方法名(形参){
// 执行代码
return 返回的定义返回类型值或对象;
}
- 加载方式可有可无 视情况而定
- 这里 return 是抛出返回值
- return 的返回值类型 必须和方法定义的时候的返回类型相同
- 方法名注意规范
关键字 | 含义 |
---|---|
return | 抛出返回值和强制停止后续代码执行 |
修饰符
修饰符(方法调用范围) | 含义 |
---|---|
public | 公共方法,可以被程序中的所有类访问。 |
private | 私有方法,只能在声明该方法的类中访问 |
protected | 受保护方法,只能被同一包内和其子类的类访问。 |
default | 同一个包内的其他类中访问,但是在包外部的类无法访问 没有修饰符修饰默认就是这个 默认不可看见 |
形参和实参
public class Demo {public static void main(String[] args) {
// 这里传入实际的值叫 实参
test(1);
}
// 这里需要传入的值叫 形参
public static void test(int a){System.out.println(a);
}
}
- 形参和方法同属一个作用域
简单使用
作用:判断 int 类型的值的大小关系
public class Demo {public static void main(String[] args) {System.out.println(max(1, 2));
}
public static int max(int a,int b){
// 返回值是变量的话 变量尽量初始化
int c = 0;
if (a == b){System.out.println("相等");
// 有错误含义的返回值 在这里起强制停止代码的作用
return 0;
}else if (a<2){c = a;}else {c = b;}
return c;
}
}
重(chong)载
定义:方法名相同 返回类型可以相同 相同的前提是形参数量必须不相同 也可以不相同
作用:方法名相同 处理不同的类型的数据 代码更美观 规范
public class Demo {public static void main(String[] args) {int[] l = {1,2,3};
int i = 1;
// 方法名相同 传入的数据类型不同
test(i);
test(l);
}
public static void test(int[] l){for (int value:l){System.out.println(value);
}
}
public static void test(int i){System.out.println(i);
}
}
静态和非静态方法
Deme 类
public class Demo {public static void main(String[] args) {
// 非静态方法 需要实例化在调用
Demo1 demo1 = new Demo1();
demo1.testNo1();
// 静态方法默认 类. 方法名() 可以直接调用
Demo1.testNo2();}
}
Deme1 类
public class Demo1 {public void testNo1(){System.out.println("非静态方法");
}
public static void testNo2(){System.out.println("静态方法");
}
}
静态方法执行代码 | 非静态方法执行代码 |
---|---|
只能引用其他属于静态类别的对象 | 可以使用非静态类别的对象 也可以使用态类别的对象 |
对一些必须使用的方法 才用静态修饰符 | 对一些不是必须使用的方法 不用静态修饰符 |
引用传递
import java.util.Arrays;
public class Demo {public static void main(String[] args) {
// 实例化 Demo2 类对象
Demo2 demo2 = new Demo2();
// 传入 demo2 类对象
Demo.test(demo2);
// 使用 demo2 类对象的 test 属性
System.out.println(demo2.test);
}
// 需要传入对象为 Demo2 类对象
public static void test(Demo2 demo2Class){
// 初始化 demo 类的 test 属性
demo2Class.test = "1";
}
}
// Demo2 类
class Demo2{String test;}
可变形参
定义:可以传入不同数量的实参
作用:数据处理更灵活
public class Demo {public static void main(String[] args) {test(1);
System.out.println();
test(1,2);
}
public static void test(int... a){for (int value:a){System.out.println(value);
}
}
}
- 在形参类型后加 "..." 代表可变形参 这个时候数据容器类型是数组
- 至少要传入一个参数
类和对象
-
对象就是类似于现实世界的物品 事件
-
类就是对对象 进行大致概括分类
-
类是对象的集合体
-
使用 new 关键字拆解对象
创建对象和使用
// 类
public class Demo {
String name;// 没有初始化 值默认为 null
int age;// 没有初始化 值默认为 0
public static void main(String[] args) {
// 相同模板不同对象
// 类的第一个对象
Demo demoNo1 = new Demo();
demoNo1.age = 18;
demoNo1.name = "yang1";
System.out.println(demoNo1.name);
System.out.println(demoNo1.age);
// 类的第二个对象
Demo demoNo2 = new Demo();
demoNo2.age = 19;
demoNo2.name = "yang2";
System.out.println(demoNo2.name);
System.out.println(demoNo2.age);
}
}
- 假如我们是造物主 对象就像人一样 我们可以设定它的 名字 年龄 上面有两个对象 分别设定他的 名字和年龄
构造器
- 构造器方法没有返回值
- 方法名必须和类名相同
- 构造器默认存在的 一般不可见
- 没有返回值类型 也是不可设定
- 其他类需要 new 这个类对象 必须要构造器
- new 本质就是在调用构造器
- 构造器支持方法重载
作用:初始化声明的对象
// 类
public class Demo {
// 声明对象
String name;
// 默认是无参构造器 默认不可见
public Demo() {}
// 有参构造器 初始化对象
public Demo(String name) {this.name = name;}
public static void main(String[] args) {
// new 本质就是在调用构造器
Demo demo = new Demo();
System.out.println(demo.name);
}
}
对象分析
类继承
父类
public class Demo1 {
public String centent;
public void function() {System.out.println("父类的方法");
}
}
子类
public class Demo2 extends Demo1{
}
实现类
// 类
public class Demo {public static void main(String[] args) {Demo2 demo2 = new Demo2();
// demo2 父类的属性
demo2.centent = "父类的属性";
System.out.println(demo2.centent);
// demo2 父类的方法
demo2.function();}
}
注意:
- 子类会继承父的 方法和属性 除了私有的 私有属性可以间接调用
- 所有的类 默认继承 Object 类 Object 类作用为入口
- 一个子类只能继承一个父类 父类只能继承一个父类的父类
- 子类是父类的扩展
super 和 this
super | this |
---|---|
指向父类 | 指向自己 |
注意:
- 都不能调用静态方法和属性 无法在静态方法中使用
父类
public class Demo1 {public Demo1(String str) {System.out.println(str);
System.out.println("父类构造器执行了");
}
public String centent;
public void demo1Function() {System.out.println("父类的方法");
}
}
子类
public class Demo2 extends Demo1{public Demo2() {// 隐藏代码 super()
super("父类有参数构造器");// 这个代码必须放在子类构造器第一行 有参构造器调用
System.out.println("子类构造器");
}
private String str;
public static void main(String[] args) {Demo2 demo2 = new Demo2();
demo2.demo2FunctionNo1();
demo2.demo2FunctionNo2();}
// super 调用父类方法和属性
public void demo2FunctionNo1(){
super.centent = "父类的属性";
System.out.println(super.centent);
super.demo1Function();}
// this 调用自己的方法和属性
public void demo2FunctionNo2(){
this.str = "自己的属性";
System.out.println(this.str);
this.demo2FunctionNo1();}
}
方法重写
定义:编写方法或覆盖方法
作用:父类的方法 子类不需要和不符合需要
注意:
- 静态方法不可被重写
- 子类重写父类的方法 父类中被重写的方法 会子类的重写方法覆盖 只作用在方法重写的子类和父类之间
- 重写只和方法有关
- 私有方法 不能被重写
- 必须要有 继承关系
- 重写方法名必须和被重写方法名相同
- 形参相同
- 范围修饰符 可以修改 从小到大
父类
public class B {public void test(){System.out.println("方法没有重写");
}
}
子类
public class A extends B{
@Override
public void test() {System.out.println("方法被重写了");
}
}
实现类
public class Main {public static void main(String[] args) {
// 方法的调用 只和左边的数据类型有关
A a = new A();
a.test();
// 子类的使用 指向父类
B b = new A();
b.test();}
}
多态
作用:
- 如功能扩展需要修改核心代码然后进行实现 用方法重写的方式间接修改代码 就算是出现问题就能很快排除错误 因为问题不在核心代码上面 一般核心代码没有问题才进行扩展
- 让人知道 子类属于那个父类(类型)的
注意:
- 要有继承关系
- 要方法重写
- 父类应用指向子类
父类
public class B {public void test(){System.out.println("父类方法");
}
}
子类
public class A extends B{
@Override
public void test() {System.out.println("子类重写");
}
}
实现类
public class Main {public static void main(String[] args) {
// 对象实际类型是确定的
// new A()
// 能调用方法和属性 是自己的和继承于父类的
A a = new A();
// 指向父类 只能使用子类继承于父类的方法和属性 方法重写就是修改了父类的方法 按照子类的想法去做 子类当家做主 类型低转高
B b = new A();
b.test();
Object c = new A();}
}
关系类型
类型判断
注意:
- 继承关系是独立的 线性的 唯一的 都有单独的关系线
- 判断两个分别处于不同关系线的继承关系 编译器会直接报错
父类
public class B {
}
子类
public class A extends B{
}
其他子类
public class C extends B{
}
实现类
public class Main {public static void main(String[] args) {
/*
关系图
Object>B>A
*/
Object object = new A();
System.out.println(object instanceof B);
System.out.println(object instanceof A);
System.out.println(object instanceof Object);
System.out.println(object instanceof C);
}
}
继承关系类型转换
注意:
- 子类转父类 要强制转换 只能使用原来父类的方法 叫向上转型
- 父类转子类 会自动转换 只能使用子类的方法 叫向下转型
父类
public class B {public void bFunction(){System.out.println("父类方法");
}
}
子类
public class A extends B{
}
实现类
public class Main {public static void main(String[] args) {A a = new A();
// 高转低 要强制转换 子类强制当父类
// 第一个括号是优先执行 第二括号是类型转换
((B)a).bFunction();}
}
Static
注意:
- 非静态方法 能调用静态或非静态方法和属性 静态方法只能调用其他静态方法或属性
- 静态方法和属性属于类对象 非静态方法和属性属于对象
//final 常量 在这里其他类不可检查该类
public final class Main {
// 静态属性
private static int age;
// 非静态属性
private int s;
// 代码块的作用 初始化和检查
{
// 匿名代码块
System.out.println("匿名代码块");
}
static{
// 静态匿名代码块
System.out.println("静态匿名代码块");
}
public Main() {System.out.println("构造器");
}
public static void main(String[] args) {
// 静态属性可以直接通过类名调用
System.out.println(Main.age);
// 静态方法可以直接通过类名调用
Main.staticFunction();
// 非静态属性 要通过类对象调用
Main main = new Main();
System.out.println(main.s);
// 非静态方法 要通过类对象调用
main.noStaticFunction();}
public static void staticFunction(){System.out.println("静态方法");
}
public void noStaticFunction(){System.out.println("非静态方法");
}
}
加载顺序 静态方法或属性或代码块>构造器>自定义对象调用
抽象类
作用:代码更简洁
注意:
- 抽象类不能 new 生成对象 进行操作 只能使用它子类的实现方法
- 抽象方法只能写在抽象类中
抽象类
package ModuleNo1;
//abstract 抽象类
public abstract class A {
// 给了一个任务 别人帮我实现
// abstract 抽象方法
// 只有方法名字 没有执行代码
public abstract void test();}
子类
package ModuleNo1;
public class B extends A{
// 约束 继承抽象类的子类必须实现抽象类定义的抽象方法
@Override
public void test() {}
}
接口
作用:制定规范
注意:
- 继承接口的子类必须实现接口的全部抽象方法
- 接口没有构造器 所以不能被 new
- 一个普通类可以继承多个接口
普通类 | 抽象类 | 接口 |
---|---|---|
只能实现方法 | 方法和规范都能实现 | 只能实现规范 |
B 接口
public interface B {// 默认和实际是 public abstract void test();
void bFunction();}
C 接口
public interface C {void cFunction();
}
A 实现类
package ModuleNo2;
public class A implements B,C{public static void main(String[] args) { }
@Override
public void bFunction() {}
@Override
public void cFunction() {}
}
内部类
public class Demo {
private int id;
public static void main(String[] args) {
// 匿名类调用
new Test().sout();
// 本质还是一个类
new ITest(){
@Override
public void test() {}
};
}
public void demoFunction(){System.out.println("外部类的方法");
}
public void classNo2(){
// 局部内部类
class classNo2_1{}}
public class classNo1{public void demoNo2Function(){System.out.println("内部类的方法");
}
public void getID(){
// 获取外部类的私有属性
System.out.println(id);
}
}
}
class Test{public void sout(){System.out.println("测试");
}
}
interface ITest{void test();
}
异常
error | exception |
---|---|
无法预料得异常 | 可以预料得异常 |
package ModuleNo3;
public class demo {public static void main(String[] args) {
int a = 1;
int b = 0;
try{
// 监控区域
System.out.println(a/b);
}catch (ArithmeticException error){//catch (想要捕获的异常 error)
// 异常处理
error.printStackTrace();// 打印错误的栈信息}finally {
// 一般用来关闭 io 流 资源
System.out.println("无论出不出异常都会执行里面的代码");
}
test(1,0);
}
// 方法处理不了异常 方法会抛出
// 方法抛出异常
public static void test(int a,int b)throws ArithmeticException{if (a == 0){throw new ArithmeticException();// 主动抛出异常 一般在方法中使用
}
System.out.println(a/b);
}
}
自定义异常
注解
常见注解
import java.sql.Array;
import java.util.ArrayList;
import java.util.List;
public class Test extends Object{
// 重写的注解
@Override
public String toString() {return super.toString();
}
// 不推荐推荐的方法 但是可以使用 注解
@Deprecated
public void test(){}
// 取消警告
@SuppressWarnings("all")
public void test1(){List list = new ArrayList();
}
public static void main(String[] args) {}}
元注解
注解的注解
import java.lang.annotation.*;
// 测试注解
@Test2
public class Test1 {
@Test2
public void test() {}
}
// 定义注解
// 定义使用范围 只能在方法中使用
//@Target(value = ElementType.METHOD)
// 定义多个使用范围 数组传入值 只能在方法和类中使用
@Target(value = {ElementType.METHOD, ElementType.TYPE})
// 定义注解什么时候有效
@Retention(value = RetentionPolicy.RUNTIME)
// 表示注解是否自定义的注解是否生成在 Java Doc 中
@Documented
// 子类可以继承父类的注解
@Inherited
@interface Test2 {}
自定义注解
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
public class Test {
// 传入参数 没有默认值就必须要传入参数
@Test1(str = "hello",i = 1,strList = {"Test"})
public void test(){}
@Test2("")
public void test1(){}
}
// 定义注解
// 定义多个使用范围 数组传入值 只能在方法和类中使用
@Target(value = {ElementType.METHOD, ElementType.TYPE})
// 定义注解什么时候有效
@Retention(value = RetentionPolicy.RUNTIME)
@interface Test1{// 注解的参数 格式:参数的类型 参数名();
// 注解的默认值 格式:default 值;
String str() default "";
// - 1 代表不存在
int i() default -1;
String[] strList() default {"没有值"};
}
// 定义注解
// 定义多个使用范围 数组传入值 只能在方法和类中使用
@Target(value = {ElementType.METHOD, ElementType.TYPE})
// 定义注解什么时候有效
@Retention(value = RetentionPolicy.RUNTIME)
@interface Test2{
// 注解只有一个参数 参数名可以使用 value
String value();}