Java基础总结
目录
Java基础
语法
- 注释
- 标识符
- 数据类型
- 类型转换
- 变量
- 常量
- 变量名命名规范!!
- 运算符
- 包机制
- Scanner对象
流程控制
- 顺序结构
- 选择结构
- 循环结构
方法
- 重载
- 可变参数
- 递归
数组
- Arraya类
- 冒泡排序
- 稀疏数组
面向对象
面向过程&面向对象(简称oo)
- 值传递和引用传递
- 类与对象的关系
- 创建对象与初始化
面向对象三大特性
- 封装
- 继承
- 多态
- 抽象类
- 接口
- 内部类
异常
- Error和Exception
- 自定义异常
- IO流
语法
注释
单行注释 //
多行注释 /* ....................*/
文档注释 /**
*
*/
标识符
Java所有组成部分都需要名字,类名,变量名以及方法名都被称为标识符。
标识符以字母,下划线,美元符号开始。
不能使用关键字作为变量名或者方法名。
标识符大小写敏感。
数据类型
Java是强类型语言,所有变量必须定义后才能使用。
Java数据类型分为两大类:基本数据类型 引用数据类型
基本数据类型: byte占1个字节 范围:-128-127
short占2个字节 范围:-32768-32767
int占4个字节 范围:-2147483648-2147483647
long占8个字节 范围:-9223372036854775808-9223372036854775897
float占4个字节
double占8个字节
char占2个字节
Boolean占1位 只有true和false两个值
引用数据类型:类 接口 数组
1字节等于8位(bit)
//八种基本数据类型//整数
int num1 = 10;
byte num2 = 20;
short num3 =30;
long num4 = 30L;//long类型要在数字后加L;
//小数,浮点数
float num5 = 50.1F;//float型要在数字后加;
double num6 = 3.1415926;
//字符
char name = 'a';
//字符串,string不是关键字,是个类。
//String namea = "abc";
//布尔 是否
boolean blog = true;
类型转换
Java是强类型语言,运算时,不同类型需转化为同一类型,然后进行计算。
int i = 128;byte b = (byte)i;//内存溢出
//强制转换 (类型)变量名 高-->低
//自动转换 低-->高
/*
注意
1.不能把布尔类型进行转换
2.不能把对象类型转化为不相干的类型
3.在把高容量转化为低容量时,强制转换
4.转化时可能存在内存溢出,或精度问题
*/
变量
Java是强类型语言,每个变量必须声明其类型。
Java变量是程序中最基本的存储单元,其要素包括变量名,数据类型和作用域。
格式: type varName = value
注意:每个变量都有类型,类型可以是基本数据类型,也可以是引用数据类型。
变量名必须是合法的标识符,变量名是一条完整的语句,以分号结尾。
public class Demo08 { //属性,变量
//类变量 static
static double salary = 2500;
//实例变量,从属于对象,不初始化会输出默认值
//布尔值 默认是false
//除了基本数据类型,其余的默认值是null
String name;
int age;
public static void main(String[] args) {
//局部变量 必须声明和初始化
int a = 10;
System.out.println(a);
//变量类型 变量名字 = new Demo08();
Demo08 demo08 = new Demo08();
System.out.println(demo08.name);
System.out.println(demo08.name);
System.out.println(salary);
}
常量
初始化后不会更改的值,用final关键字修饰,常量名一般使用大写字母。
public class Demo09 { //修饰符,没有先后顺序
static final double PI = 3.14;
public static void main(String[] args) {
System.out.println(PI);
}
}
变量名命名规范!!
所有的变量,方法,类名;见名知意。
类成员变量,局部变量:首字母小写和驼峰原则,例:mouthSalary。
方法名:首字母小写和驼峰原则,例:mouthSalary()。
常量:大写字母和下划线,MAX_VALUE。
类名:首字母大写和驼峰原则。
运算符
算术运算符:+,-,*,/,%,++,--
//++ -- 自增 自减 一元运算符int a = 3;
int b = a++;//给b赋值后自增
int c = ++a;//自增后赋值给c
赋值运算符:=
关系运算符:>, <, >=, <=, ==, !=instanseof
逻辑运算符:&&, ||, !
//与(and) 或(or) 非(取反)boolean a = true;
boolean b = false;
System.out.println("a && b: "+(a&&b));//逻辑与运算,两个变量都为真,结果才为true
System.out.println("a || b: "+(a||b));//逻辑或运算,两个变量有一个为真,结果就为true
System.out.println("!(a&&b):"+!(a&&b));//如果是真变为假,是假变为真
//短路运算
int c = 5;
boolean d = (c<4)&&(c++<4);//c小于4为假,直接返回false,不执行后面的
System.out.println(d);
System.out.println(c);
位运算符:&, |, ^, >>, <<, >>>(了解)
public static void main(String[] args) { /*
A = 0011 1100
B = 0000 1101
A&B = 0000 1100 两个都为1才为1,其他都为0
A|B = 0011 1101 两个都为0才为0,其他都为1
A^b = 0011 0001 两个相同为0,不同为1
~B = 1100 0010 取反
2*8 按位运算效率最快
0000 0001 1
0000 0010 2
0000 0100 4
0000 1000 8
0001 0000 16
*/
System.out.println(2<<3);
}
条件运算符:? :
public static void main(String[] args) { //x ? y : z
//如果x为true,结果为y,否则为z
int score = 88;
String result = score < 60 ?"不及格":"及格";
System.out.println(result);
}
拓展赋值运算符:+=, -=, *=, /=
包机制
为了更好地组织类,Java提供了包机制,用于区别类名的命名空间。
一般用公司域名倒置作为包名。
为了能够使用某一个包的成员,可使用import导入该包。
Scanner对象
java.util.Scanner是Java5的新特性,我们可以通过Scanner来获取用户的输入。
通过Scanner类的next()和nextLine()获取输入的字符串。
public static void main(String[] args) { //创建一个扫描器对象,接受键盘输入
Scanner scanner = new Scanner(System.in);
System.out.println("使用next方法接受:");
//判断用户是否输入字符串
if (scanner.hasNext()){
String str = scanner.next();
System.out.println("输入的内容为:"+str);
}
//属于 IO流的内容不关闭会一直占用资源
scanner.close();
}
public static void main(String[] args) { //创建一个扫描器对象,接受键盘输入
Scanner scanner = new Scanner(System.in);
System.out.println("使用nextLine方法接受:");
//判断用户是否输入字符串
if (scanner.hasNextLine()){
String str = scanner.nextLine();
System.out.println("输入的内容为:"+str);
}
//属于 IO流的内容不关闭会一直占用资源
scanner.close();
}
next(): 一定检测到有效字符串后才可以结束输入。
对输入有效字符串之前遇到的空白,会自动将其去掉。
输入有效字符后再输入空白会当作分隔符或结束符(next()不能得到有空格的字符串)。
nextLine(): 以Enter为结束符,会输出回车之前所有的字符,可以得到空白。
流程控制
顺序结构
顺序是最简单的算法结构,它由若干个依次执行的步骤组成,是任何一个算法都离不开的基本算法结构。
选择结构
public static void main(String[] args) { Scanner scanner = new Scanner(System.in);
System.out.println("请输入成绩:");
int s= scanner.nextInt();
//判断成绩
if (0<=s&&s<60){
System.out.println("不及格");
}else if (s<80){
System.out.println("良好");
}else if (s<=100){
System.out.println("优秀");
}
else {
System.out.println("输入成绩不合法!");
}
scanner.close();
}
swith选择结构:判断一个变量与一系列值中某个值是否相等,case称为分支(JDK7后,swith支持字符串比较)。
public static void main(String[] args) { //switch
char grade = 'C';
switch (grade){
case 'A':
System.out.println("优秀");
break;//防止case穿透
case 'B':
System.out.println("良好");
break;
case 'C':
System.out.println("及格");
break;
default:
System.out.println("未知等级");
}
}
循环结构
while循环;do...while循环(至少被执行一次);for循环。
public static void main(String[] args) { //输出1-100的和
int i = 0;
int sum = 0;
while (i<100){
i++;
sum+=i;
}
System.out.println(sum);
}
public static void main(String[] args) { //输出1-100的和
int i = 0;
int sum = 0;
do {
i++;
sum+=i;
}
while (i<100);
System.out.println(sum);
}
foe循环是支持迭代的一直=中通用结构,是最有效,最灵活的循环结构(for循环的次数是在执行前就明确的)。
public static void main(String[] args) { //计算100内的奇数和与偶数和
int oddSum = 0;
int evenSum = 0;
for (int i = 0; i < 100; i++) {
if (i%2==0){
oddSum+=i;
}else {
evenSum+=i;
}
}
System.out.println("偶数和"+oddSum);
System.out.println("奇数和"+evenSum);
}
public static void main(String[] args) { //1000能被5整除的数,并且每行输出3个
for (int i = 0; i < 1000; i++) {
if (i%5==0){
System.out.print(i+"\t");
}
if (i%(5*3)==0){
System.out.println();
}
}
}
public static void main(String[] args) { //99乘法表
for (int i = 1; i <= 9; i++) {
for (int j = 1; j <= i; j++) {
System.out.print(i+"*"+j+"="+(i*j)+"\t");
}
System.out.println();
}
}
public static void main(String[] args) { //输出三角形
for (int i = 1; i <= 6; i++) {
for (int j = 6; j >= i; j--) {
System.out.print(" ");
}
for (int k = 1; k <= i; k++){
System.out.print("*");
}
for (int k = 1; k < i; k++){
System.out.print("*");
}
System.out.println();
}
}
增强for循环(Java5引入,主要用于数组或者集合)
public static void main(String[] args) { //增强for
int[] numbers = {10,20,30,40,50};
//遍历数组
for (int x:numbers){
System.out.println(x);
}
}
break用于强行退出循环,不执行循环后的语句。
continue用于终止某次循环,即跳过循环中尚未执行的语句,接着进行下一次是否执行循环的判定。
public static void main(String[] args) { //break
int a = 0;
while (a<88){
a++;
System.out.println(a);
if (a==22){
break;
}
}
}
public static void main(String[] args) { //continue
int i = 0;
while (i<100){
i++;
if (i%10==0){
System.out.println();
continue;
}
System.out.print(i);
}
}
方法
Java方法是语句的集合,它们在一起执行一个功能。
方法是解决一类问题的步骤的有序集合,方法包含在类或对象中,方法在程序中创建,在其它地方被调用。
设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块集合,我们设计方法的时候最好保持方法的原子性,就是一个方法只完成一个功能,这样便于我们后期的拓展。
方法的定义:Java的方法类似与其他语言的函数,是一段用来完成特定功能的代码片段。
方法由方法头和方法体组成,下面是一个方法的所有部分:
修饰符:修饰符是可选的,告诉编译器如何调用该方法,定义方法的访问类型。
返回值类型:方法可能会有返回值,returnValueType是方法返回值的类型,没有返回值的方法,returnValueType是关键字void。
方法名:是方法的实际名称,方法名和参数表共同构成方法签名。
参数类型:参数像是一个占位符,当方法被调用时,传递值给参数;参数列表是指方法的参数类型,顺序,和参数的个数。参数的可 选的,方法可以不包含任何参数。形参:方法调用时用于接收外界输入的数据,实参:调用方法时实际传递给方法的数 据。
方法体:包含具体的语句,定义该方法的功能。
public static void main(String[] args) { add(2,3);
}
//加法
public static void add(int a,int b){
int sum;
sum = a + b;
System.out.println(sum);
}
重载
重载就是在一个类中,有相同的函数名称,但形参不同的函数。
方法重载的规则:方法名必须相同;参数列表必须不同(个数,类型,或参数顺序不同);方法的返回值可以相同也可以不相同;仅仅方 法返回类型不同不足以成为方法的重载。
实现理论:方法名相同时,编译器会根据调用方法的参数个数,参数类型等去逐个匹配,以选择对应的方法,若匹配失效,会报错。
可变参数
一个方法中只能指定一个可变参数,它必须是方法的最后一个参数,任何普通参数必须在它之前声明。
public static void main(String[] args) { //参数类型必须一样
test(1,2,3);
}
public static void test(int...i){
System.out.println(i[0]);
System.out.println(i[1]);
System.out.println(i[2]);
}
递归
递归结构包括两个部分;递归头:什么时候不调用自身方法,如果没有头,将陷入死循环。递归体:什么时候需要调用自身方法。
public static void main(String[] args) { //输出5的阶乘
System.out.println(f(5));
}
//在栈操作,基数小的时候使用递归,基数大时候会出现内存崩溃
public static int f(int n){
if (n==1){
return 1;
}else {
return n*f(n-1);
}
}
数组
数组是相同类型数据的有序结合。每一个数据称为数组元素,每个数组元素可以通过下标来访问(下标从0开始)。
数组声明创建:首先必须声明数组变量才能在程序中使用,Java用new操作符来创建数组。
public static void main(String[] args) { //声明数组
int[] nums1;//首选定义的方法
int nums2[];//效果相同,不推荐
//创建数组
nums1 =new int[4];//可以存放4个int类型的数字
nums1[0] = 1;
nums1[1] = 2;
nums1[2] = 3;
nums1[3] = 4;
System.out.println(nums1[2]);
//求数组元素的和
int sum =0;
//获取数组的长度 array.length
for (int i = 0; i < nums1.length; i++) {
sum+=nums1[i];
}
System.out.println("数组的和为:"+sum);
}
数组的三种初始化:1.静态初始化;2.动态初始化;3.数组的默认初始化:数组是引用类型,它的元素相当于类的实例变量,因此数组一 经分配空间,其中的每个元素也会被按照实例变量的方式被隐式初始化。
public static void main(String[] args) { //静态初始化
int[] a = {1,2,3,4,5};
//动态初始化 包含默认初始化
int[] b = new int[10];
b[0] = 1;
System.out.println(b[0]);
System.out.println(b[1]);
}
数组的基本特点:
数组的长度是确定的,一旦被创建,长度就不可以改变(如果越界,会出现数组下标越界异常)。
数组的元素必须是相同的类型。
数组中元素可以是任意数据类型,包括基本类型和引用类型。
数组变量属引用类型,数组可以看成是对象,数组中每个元素相当于该对象的成员变量。数组本身就是对象,Java对象是在堆中的,因 此无论数组保存原始类型还是其他对象类型,数组对象本身是在堆中的。
public static void main(String[] args) { int[] arrays = {1, 2, 3, 4, 5};
for (int array : arrays) {
System.out.print(array);
}
//打印数组
System.out.println();
printArray(arrays);
//输出反转数组
System.out.println();
printArray(reverse(arrays));
}
//反转数组
public static int[] reverse(int[] arrays){
int[] result = new int[arrays.length];
for (int i = 0,j = result.length-1; i < arrays.length; i++,j--) {
result[j] = arrays[i];
}
return result;
}
//打印数组
public static void printArray(int[] arrays) {
for (int i = 0; i < arrays.length; i++) {
System.out.print(arrays[i]);
}
}
二维数组:每一个元素都是一个一维数组。
public static void main(String[] args) { //二位数组
int[][] arrays = {{1, 2}, {2, 3}, {3, 4}};
printArray(arrays[0]);
System.out.println();
System.out.println(arrays[0][0]);
System.out.println(arrays[0][1]);
}
//打印数组
public static void printArray(int[] arrays) {
for (int i = 0; i < arrays.length; i++) {
System.out.print(arrays[i]);
}
}
Arraya类
数组工具类java.util.Arrays
Arrays类中的方法都是static修饰的静态方法,在使用的搜索可以直接使用类名进行调用,而不用使用对象来调用(不用而不是不能)。
有以下功能:数组赋值:fill方法; 数组排序:sort方法,按升序; 比较数组:equals方法;
查找数组元素:通过binarySearch方法能对排序好的数组进行二分查找法操作。
public static void main(String[] args) { int[] a = {1, 22, 31, 3, 5, 14, 88};
System.out.println(a);//输出的是hashcode值
System.out.println(Arrays.toString(a));//Arrays的toString方法输出数组
printArray(a);
}
//自己的方法输出数组
public static void printArray(int[] a) {
for (int i = 0; i < a.length; i++) {
if (i == 0) {
System.out.print("[");
}
if (i == a.length - 1) {
System.out.print(a[i]+"]");
} else {
System.out.print(a[i] + ", ");
}
}
}
冒泡排序
冒泡排序是八大算法中最出名的排序算法之一,外层冒泡轮数,里层依次比较,时间复杂度为O(n2)。
public static void main(String[] args) { //定义数组
int[] array = {3,4,1,2,77,31,22,41};
//调用排序方法
int[] sort = sort(array);
//输出
System.out.println(Arrays.toString(sort));
}
//冒泡排序
//1.比较数组中相邻两个元素的大小,如果第一个比第二个大就交换它们的位置
//2.每一次比较,都会得到一个最大或最小的数字
//3.依次循环,直到结束
public static int[] sort(int[] array){
//临时变量
int temp = 0;
//外层循环,判断循环多少次
for (int i = 0; i < array.length-1; i++) {
//j一轮循环后会得到一个最大的数,i代表倒着数已经排好的数
for (int j = 0; j < array.length-1-i; j++) {
//如果第一个比第二个大就交换位置
if (array[j]>array[j+1]){
temp = array[j];
array[j] = array[j+1];
array[j+1] = temp;
}
}
}
return array;
}
稀疏数组
稀疏数组:当一个数组中的大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存。
稀疏数组的处理方式是:记录数组一共有几行几列,有多少个不同值;把具有不同值的元素的行列和值记录在一个小规模的数组中,从而 缩小程序规模。
public static void main(String[] args) { //创建二维数组11*11 0.没有棋子 1.黑棋 2.白棋
int[][] array1 = new int[11][11];
array1[1][2] = 1;
array1[2][3] = 2;
//输出原始数组
System.out.println("原始的数组为:");
for (int[] ints : array1) {
for (int anInt : ints) {
System.out.print(anInt + "\t");
}
System.out.println();
}
//转化为稀疏数组保存
//获取有效值的个数
int sum = 0;
for (int i = 0; i < 11; i++) {
for (int j = 0; j < 11; j++) {
if (array1[i][j] != 0) {
sum++;
}
}
}
System.out.println("有效值的个数:" + sum);
//创建一个稀疏数组
int[][] array2 = new int[sum + 1][3];
array2[0][0] = 11;
array2[0][1] = 11;
array2[0][2] = sum;
//遍历二维数组,将非0的数存放到稀疏数组中
int count = 0;
for (int i = 0; i < array1.length; i++) {
for (int j = 0; j < array1[i].length; j++) {
if (array1[i][j] != 0) {
count++;
array2[count][0] = i;
array2[count][1] = j;
array2[count][2] = array1[i][j];
}
}
}
//输出稀疏数组
System.out.println("稀疏数组");
for (int j = 0; j < array2.length; j++) {
System.out.println(array2[j][0] + "\t"
+ array2[j][1] + "\t"
+ array2[j][2]);
}
//还原
System.out.println("还原稀疏数组");
//读取稀疏数组
int[][] array3 = new int[array2[0][0]][array2[0][1]];
//给其他元素还原它的值 第0行存的是头部信息行和列,从第一行开始读取
for (int i = 1; i < array2.length; i++) {
array3[array2[i][0]][array2[i][1]] = array2[i][2];
}
//打印
System.out.println("原始的数组为:");
for (int[] ints : array1) {
for (int anInt : ints) {
System.out.print(anInt + "\t");
}
System.out.println();
}
}
面向对象
面向过程&面向对象(简称oo)
面向过程思想:步骤清晰简单,第一步做什么,第二步做什么... 面向过程适合处理一些较为简单的问题。
面向对象思想:物理类聚,分类的思维模式,思考问题首先会把需要解决的问题分类,然后对这些分类进行单独的思考,最后才对某个分 类下的细节进行面向过程的思考;面向过程适合处理复杂的问题,适合多人协同的问题。
对于描述复杂的事物,为了从宏观上把握,从整体上合理分析,我们需要使用面向对象的思想来分析整个系统,但是,具体到细微操作,仍然需要面向过程的思想去处理。
面向对象编程(OOP)的本质就是:以类的方式组织代码,以对象组织(封装)数据。
三大特征:封装,继承,多态。
从认知角度考虑是先有对象后有类,对象是具体的事物,类是抽象的,是对对象的抽象。
从代码的角度是先有类后有对象,类是对象的模板。
值传递和引用传递
public class Demo04 { public static void main(String[] args) {
//值传递
int a = 1;
Demo04.change(a);
System.out.println(a);//a=1
}
public static void change(int a){
a =10;
}
}
public class Demo05 { //引用传递,对象;本质是值传递
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name);//null
Demo05.change(person);
System.out.println(person.name);//zzr
}
public static void change(Person person){
//person是一个对象
person.name = "zzr";
}
}
//定义一个Person类,有一个属性name
class Person{
String name;
}
类与对象的关系
类是一种抽象的数据类型,它是对某一事物的具体描述/定义,但是并不能代表某一个事物。
对象是抽象概念的具体实例。
创建对象与初始化
使用new关键字创建对象,创建时会分配内存空间,还会给创建好的对象进行默认的初始化以及对类中默认构造器的调用。
类中的构造器也称为构造方法(类都有一个默认的构造方法),是在创建对象时必须调用的。
构造器有以下特点:必须和类的名字相同,必须没有返回类型,也不能写void。
package com.oop.Demo02;//学生类
public class Student {
//属性 字段
String name;
int age;
//方法
public void study(){
System.out.println(this .name+"在学习");
}
}
package com.oop.Demo02;public class Application {
//规范一个项目只有一个main方法
public static void main(String[] args) {
//类是抽象的,需要实例化
//类实例化会方法一个自己的对象
//student对象就是Student类的一个具体实例
Student student = new Student();
Student student1 = new Student();
student.name = "小明";
student.age = 18;
System.out.print(student.name);
System.out.println(student.age);
student1.name = "小红";
student1.age = 16;
System.out.print(student1.name);
System.out.println(student1.age);
}
}
构造器
package com.oop.Demo02;public class Person {
//Alt+insert 快捷键生成构造器
//类有默认的构造方法
String name;
//默认构造器
//使用new关键字,本质是在调用构造器
//用来初始化值
public Person(){
}
//有参构造 定义了有参构造 无参构造就必须定义显示出来
public Person(String name){
this.name = name;
}
}
package com.oop.Demo02;public class Application {
//规范一个项目只有一个main方法
public static void main(String[] args) {
//实例化一个对象
Person person = new Person();
System.out.println("zhou");
}
}
面向对象三大特性
封装
Java三大特性:封装,继承,多态。
我们的程序设计要求“高内聚,低耦合”,高内聚就是类的内部数据操作细节由自己完成,不允许外部干涉,低耦合,仅暴露少量的方法供外部使用。
封装(数据的隐藏 属性私有 get/set):通常,应禁止访问一个对象中数据的实际展示,而应通过接口来访问,这称为信息隐藏。
package com.oop.Demo03;//类
public class Student {
private String name;//名字
private int id;//学号
private char sex;//性别
private int age;//年龄
//ALt+insert 快捷键生成get/set方法
//提供一些可供操作这个属性的方法
//get 获取这个属性 set设置属性的值
public String getName(){
return this.name;
}
public void setName(String name){
this.name = name;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if (age>120||age<0){
this.age = 3;
}else {
this.age = age;
}
}
}
package com.oop.Demo03;public class Application {
/*
1.提高程序安全性 保护数据
2.隐藏代码的实现细节
3.统一接口
4.提高系统的可维护性
*/
public static void main(String[] args) {
//实例化一个对象
Student s1 = new Student();
s1.setName("周周");
System.out.println(s1.getName());
s1.setAge(88);
System.out.println(s1.getAge());
}
}
继承
继承的本质是对某一批类的抽象,从而实现对现实世界更好的建模。
Java中只有单继承,没有多继承;继承关键字 extends。
继承是类和类之间的一种关系,除此之外,类和类之间的关系还有依赖,组合,聚合等。
继承关系的两个类,一个为子类(派生类),一个为父类(基类),子类和父类i之间从意义上讲具有“is a”的关系。
Object是所有类的父类。
package com.oop.Demo04;public class Person {
//public 公共的
//protect 受保护的
//default 默认的(不写)
//private 私有的
public int money = 100000000;
private int money1 = 10000;
public void say(){
System.out.println("说话");
}
public int getMoney1() {
return money1;
}
public void setMoney1(int money1) {
this.money1 = money1;
}
}
package com.oop.Demo04;//子类继承父类就会拥有父类的所有方法
public class Student extends Person{
}
package com.oop.Demo04;public class Application {
public static void main(String[] args) {
Student student = new Student();
student.say();//调用父类方法
student.getMoney1();//调用父类私有属性
System.out.println(student.getMoney1());
}
}
super()调用父类的构造方法,必须在构造方法的第一个。
super必须只能出现在子类的方法或者构造方法中。
super和this不能同时调用构造方法。
this:本身调用者这个对象;super代表父类的对象 。
this在没有继承时也i可以使用,super只能在继承条件下才可以使用。
this():本类的构造;super():父类的构造。
package com.oop.Demo05;public class Person {
public Person() {
System.out.println("person无参执行了");
}
public void print(){
System.out.println("Person");
}
}
package com.oop.Demo05;//子类继承父类就会拥有父类的所有方法
public class Student extends Person {
public Student() {
//默认调用父类的无参构造
//super()调用父类的构造方法,必须在构造方法的第一个
System.out.println("Student无参执行了");
}
public void print(){
System.out.println("Student");
}
public void test1(){
print();//Stdent
this.print();//Student
super.print();//Teacher
}
}
package com.oop.Demo05;public class Application {
public static void main(String[] args) {
Student student = new Student();
//student.test1();
}
}
重写:有继承关系,子类重写父类的方法,方法名相同方法体不同,非静态的方法才可以重写。
必要条件:方法名必须相同,参数列表必须相同,修饰符范围可以扩大不能缩小。抛出的异常范围可以被缩小不能被放大。
静态方法
package com.oop.Demo06;public class B {
public static void test(){
System.out.println("B>>test()");
}
}
package com.oop.Demo06;public class A extends B{
public static void test(){
System.out.println("A>>test()");
}
}
package com.oop.Demo06;public class Application {
public static void main(String[] args) {
A a = new A();
a.test();//A>>test()
//父类的引用指向子类
B b = new A();
b.test();//B>>test()
}
}
非静态方法
package com.oop.Demo06;public class B {
public void test(){
System.out.println("B>>test()");
}
}
package com.oop.Demo06;public class A extends B{
//重写
@Override //注解 有功能的注释
public void test(){
System.out.println("A>>test()");
}
}
package com.oop.Demo06;public class Application {
public static void main(String[] args) {
//静态方法和非静态方法区别很大
A a = new A();
a.test();//A>>test()
//父类的引用指向子类
B b = new A();//子类重写了父类的方法
b.test();//A>>test()
}
}
多态
多态:即同一个方法可以根据发送对象的不同而采用多种不同的行为方式。
一个对象的实际类型是确定的,但可以指向对象的引用类型有很多。
多态存在的条件:有继承关系,子类重写父类的方法,父类引用指向子类的对象。
注意:多态是指方法的多态,属性没有多态。static(方法属于类不属于实例),final(常量),private方法不能重写,不能实现多态。
package com.oop.Demo07;public class Person {
public void run(){
System.out.println("run");
}
}
package com.oop.Demo07;public class Student extends Person {
@Override
public void run() {
System.out.println("son");
}
public void eat(){
System.out.println("eat");
}
}
package com.oop.Demo07;public class Application {
public static void main(String[] args) {
//一个对象的实际类型是确定的
//new Student();
//new Person();
//可以指向的引用类型是不确定的,父类的引用指向子类
//Student能调用的方法都是自己的或者继承父类的
Student s1 = new Student();
//Person父类型 可以指向子类 但不能调用子类独有的方法
Person s2 = new Student();
Object s3 = new Student();
s2.run();//子类重写了父类的方法,执行子类的方法
s1.run();
//对象能执行哪些方法,主要看对象左边的类型
s1.eat();
}
}
instanceof (类型转换) 引用类型
package com.oop.Demo08;public class Person {
}
package com.oop.Demo08;public class Student extends Person {
public void go() {
System.out.println("go");
}
}
package com.oop.Demo08;public class Teacher extends Person {
}
package com.oop.Demo08;public class Application {
public static void main(String[] args) {
Object object = new Student();
System.out.println(object instanceof Student); //true
System.out.println(object instanceof Person); //true
System.out.println(object instanceof Object); //true
System.out.println(object instanceof Teacher); //false
System.out.println(object instanceof String); //false
}
}
public class Application { public static void main(String[] args) {
//类型之间的转换 父 子
//高-->低
Person obj = new Student();
//student将这个类型转化为Student类型,我们就可以使用Student类型的方法
Student student = (Student) obj;
student.go();
}
}
静态
//staticpublic class Student {
private static int age; //静态变量
private double score; //非静态变量
//非静态方法可以调用静态方法
public void run(){
go();
}
//static和类一起加载
public static void go() {
}
public static void main(String[] args) {
Student s1 = new Student();
System.out.println(Student.age);
System.out.println(s1.age);
System.out.println(s1.score);
go();
new Student().run();
}
}
public class Person { {
//匿名代码块
System.out.println("匿名代码块");
}
static {
//静态代码块 最先执行 只执行一次
System.out.println("静态代码块");
}
public Person() {
System.out.println("构造方法");
}
public static void main(String[] args) {
Person person1 = new Person();
System.out.println("===============");
Person person2 = new Person();
}
}
//静态导入包import static java.lang.Math.PI;
import static java.lang.Math.random;
public class Test {
public static void main(String[] args) {
//System.out.println(Math.random());
System.out.println(random());
System.out.println(PI);
}
}
抽象类
abstract修饰符如果修饰方法,那么该方法是抽象方法,如果修饰类那么该类就是抽象类。
抽象类中可以没有抽象方法,但是抽象方法的类一定要声明为抽象类。
抽象类不能用new关键来创建对象,它是用来让子类继承的。
抽象方法,只有方法的声明,没有方法的实现,它是用来让子类实现的。
子类继承抽象类,那么就必须实现抽象类没有实现的抽象方法,否则该子类也要声明为抽象类。
//抽象来public abstract class Action {
//抽象方法 只有方法的名字 没有方法的实现
public abstract void doSameThing();
//不能new抽象来 只能子类去实现
//抽象类中可以有普通方法 抽象方法只能在抽象方法中
}
//子类必须实现父类的抽象方法 除非子类也是抽象类public class A extends Action {
@Override
public void doSameThing() {
}
}
接口
普通类:只有具体实现,声明用class。
抽象类:具体实现和规范(抽象方法)都可以有,声明用abstract。
接口:只有规范(抽象方法),自己无法写方法,约束和实现分离,声明用intenface。
接口就是规范,定义的一组规则;接口的本质是契约,就像人间的法律一样,制定好后大家都去遵守。
如果一个接口只有一个抽象方法,那么该接口就是一个函数式接口。
函数式接口的实例可以通过 lambda 表达式、方法引用或者构造方法引用来创建。
oo(面向对象)的精髓,是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计模式都只针对具备了抽象能力的语言(如Java,C++,C#等),就是因为设计模式所研究的,实际上就是如何合理地区抽象。
//接口 接口需要有实现类public interface UserService {
//接口中的所有定义其实都是抽象的 默认public abstract修饰
void add(String name);
void delete(String name);
void update(String name);
void query(String name);
}
package com.oop.Demo11;public interface TimeService {
void timer();
}
//类通过implements实现接口//实现了接口的类 就需要实现接口中所有的方法
//利用接口实现多继承
public class UserServiceImpl implements UserService,TimeService{
@Override
public void add(String name) {
}
@Override
public void delete(String name) {
}
@Override
public void update(String name) {
}
@Override
public void query(String name) {
}
@Override
public void timer() {
}
}
内部类
内部类就是在一个类的内部再定义一个类,比如A类中定义了一个B类,B就是A的内部类,A是B的外部类。
成员内部类
public class Outer { public void out(){
System.out.println("这是外部类的方法");
}
public class Inner{
public void in(){
System.out.println("这是内部类的方法");
}
//获取外部类的私有属性
public void getId(){
System.out.println(id);
}
}
}
public class Application { public static void main(String[] args) {
Outer outer = new Outer();
Outer.Inner inner = outer.new Inner();
inner.in();
inner.getId();
}
}
静态内部类
public class Demo { private int id = 10;
public void out(){
System.out.println("这是外部类的方法");
}
public static class Inner{
public void in(){
System.out.println("这是内部类的方法");
}
}
}
局部内部类
public class Demo01 { //局部内部类
public void method(){
class inner{
public void in() {
}
}
}
}
匿名内部类
public class Demo02 { public static void main(String[] args) {
//没有名字初始化类 不用将实例保存到变量中
new Apple().eat();
//接口的匿名内部类
new UserService(){
@Override
public void hello() {
}
};
}
}
class Apple{
public void eat(){
System.out.println("1");
}
}
interface UserService{
void hello();
}
异常
什么是异常:实际生活中,会遇到各种各样的情况,比如,你写的某一个模块,用户的输入不一定符合你的要求,你的程序要打开某个文件,但这个文件可能不在或者格式不对等情况。
软件程序在运行的过程中可能会遇到以上的非法参数,文件找不到问题,我们叫异常(exception)。
异常发生在程序运行期间,它影响了正常的程序执行流程。
public static void main(String[] args) { System.out.println(11/0); //java.lang.ArithmeticException
}
检查性异常:用户输入错误引起的异常,这是程序员无法遇见的。
运行时异常:运行时异常是可能被程序员避免的异常,与检查性异常相反,运行时异常可以在编译时被忽略。
错误:错误不是异常,而实脱离程序员控制的问题,错误在代码中通常被忽略。例如:当栈溢出时,错误就发生了,在编译时检查不到。
Java把异常当一个对象来处理,并定义一个基类java.lang.Throwable作为所有异常的基类。
Throwable: 分为Error 和 Exceotion。
Error分为AWTError和 VirtuMachineError, VirtualMachineError有StackOverFlowError和OutOfMemoryError。
Exception: IOException和RuntimeException,IOException有EOFException和FileNotFoundException, RuntimeException有 ArrithmeticException(算数异常), MissingResouurceException(丢失资源), ClassNotFoundException(找不到类), NullPointerException(空指针异常), ArrayIndexOutBoundsException(数组下标越界), UnKownException等...
Error类对象由Java虚拟机生成并抛出,大多数错误与代码编写者所执行的操作无关。
Java虚拟机运行错误( VirtualMachineError),当JVM不在有继续执行操作所需的内存资源时,将出现OutOfMemoryError,这些异常 发生时,Java虚拟机一般会选择线程终止。
还有些发生在虚拟机试图执行应用时,如类定义错误(NoClassDefFoundError),链接错误(LinkageError),这些错误时不可察的,因为它们在应用程序的控制和处理能力之外,而且大多数是程序运行的时不允许出现的状况。
Exception一般有程序逻辑错误引起的,程序应从逻辑角度尽可能避免这类异常的方法。
Error和Exception
Error和Exception的区别:Error是灾难性的致命错误,是程序无法控制处理的,当出现这类情况时,Java虚拟机一般会选择终止线程。Exception通常情况下是可以被程序处理的,并且在程序中应尽可能的去处理这些异常。
异常处理机制:抛出异常,处理异常。
catch可以捕获多个异常,但要把范围小的写在前面。
无论出不出异常,finally的代码块都会被执行(finally可以不写),但是尽量添加finally代码块去释放占用的资源。
对于不确定的代码,可以加上try-catch去处理潜在的异常。
public class Test { public static void main(String[] args) {
int a = 2;
int b = 0;
try {
System.out.println(a/b);
}catch (ArithmeticException e) {//catch(想要捕获的异常)
System.out.println("分母不能为0");
}catch (Exception e) {//catch(想要捕获的异常)
System.out.println("Exception");
}finally {//处理善后工作
System.out.println("finally");
}
}
}
public class Test02 { public static void main(String[] args) {
new Test02().test(2,0);
}
public void test(int a,int b){
if(b==0){
throw new ArithmeticException();//主动抛出异常 一般在方法中使用
}
System.out.println(a/b);
}
}
public class Test03 { public static void main(String[] args) {
try {
new Test03().test(2,0);
} catch (ArithmeticException e) {
e.printStackTrace();
}
}
//假设方法中处理不了这个异常,方法上抛出异常
public void test(int a,int b) throws ArithmeticException{
if(b==0){
throw new ArithmeticException();//主动抛出异常 一般在方法中使用
}
}
}
自定义异常
使用Java内置的异常可以描述在编程时出现的大部分异常情况,除此之外,还可以自定义异常,只需继承Exception类即可。
在程序中使用自定义异常,大体分为以下步骤:
1.创建自定义有效类。
2.在方法中通过throw关键字抛出异常。
3.如果在当前抛出异常的方法中处理异常,可以使用try-catch捕获并处理,否则在方法的声明处通过throws关键字指明要抛出给方法调 用者的异常,进行下一步操作。
4.在出现异常方法的调用者中捕获并处理异常。
package com.exception;//自定义异常
public class MyExcepyion extends Exception{
//传递数字
private int detail;
public MyExcepyion(int a) {
this.detail = a;
}
//toString 异常的打印信息
@Override
public String toString() {
return "MyExcepyion{" +
"detail=" + detail +
'}';
}
}
package com.exception;public class TestException {
//可能在异常的方法
static void test(int a) throws MyExcepyion {
System.out.println("传递的参数为:"+a);
if(a>10){
throw new MyExcepyion(a);
}
System.out.println("ok");
}
public static void main(String[] args) {
try {
test(11);
} catch (MyExcepyion e) {
System.out.println("MyException-->"+e);
}
}
}
IO流
流:代表任何有能力产出数据的数据源对象或者有能力接收数据的接收端对象。----Thinking in java
本质:主要用于数据传输,Java用于操作流的对象都在IO包中。
数据流方向分类:分为输入流和输出流
处理数据单位分类分为:字节流和字符流,1字符=2个字节,1字节=8位,一个汉字占两个字节。
- 字节流:一次读取一个字节,读取汉字会出现乱码,一般用来读取图片,视频,word等格式的文件。
- 字符流:一次读取两个字节,一般用来处理纯文本文件类型的文件(中文),不能处理图片,视频等非文本文件。
字节字符流的转换:文本文件在硬盘中以字节流的形式存储时,通过InputStreamReader读取后转化为字符流给程序处理,程序处理的字符流通过OutputStreamWriter转换为字节流保存。
字符流和字符流的区别:读写的单位不同,处理的对象不同,节流没有缓冲区,是直接输出的,而字符流是输出到缓冲区的。因此在输出时,字节流不调用colse()方法时,信息已经输出了,而字符流只有在调用close()方法关闭缓冲区时,信息才输出。要想字符流在未关闭时输出信息,则需要手动调用flush()方法。
处理流BufferedReader,BufferedWriter,BufferedInputStream,BufferedOutputsStream:带Buffer的流称为缓冲流,内部有一个缓冲区来存放字节,待缓冲区满后一次发送,不是一个字节一个字节的发送,提高效率。
读取文件(读出来的时ASCII码)
public class Demo01 { public static void main(String[] args) throws IOException {
//文件的路径
File file = new File("D:\\a.txt");
//得到文件的输入流
InputStream fis = new FileInputStream(file);
//读取文件
int result = 0;
while ((result=fis.read())!=-1){
System.out.println(result);
}
//关流
fis.close();
}
}
读取文件(真实的数值)
public class Demo02 { public static void main(String[] args) throws IOException {
//文件的路径
File file = new File("D:\\a.txt");
//得到文件的输入流
InputStream fis = new FileInputStream(file);
//读取文件
int result = 0;
byte[] buffer = new byte[1024];
while ((result=fis.read(buffer))!=-1) {
String res = new String(buffer,0,result);
System.out.println(res);
}
//关流
fis.close();
}
}
复制文件
public class Demo03 { public static void main(String[] args) throws IOException {
//文件的路径
File file = new File("D:\\a.txt");
File file1 = new File("D:\\b.txt");
//得到文件的输入流
InputStream fis = new FileInputStream(file);
//文件输出到file1中
FileOutputStream fos = new FileOutputStream(file1);
//读取文件
int result = 0;
byte[] buffer = new byte[1024];
while ((result=fis.read(buffer))!=-1) {
fos.write(buffer,0,result);
}
//关流
fos.close();
fis.close();
}
}
文件中写入数据
public class Demo04 { public static void main(String[] args) throws IOException {
//文件的路径
File file = new File("D:\\a.txt");
//得到文件的输入流
FileOutputStream fos = new FileOutputStream(file);
fos.write("小明在学习!".getBytes());
}
}
使用BufferedInputStream
public class Demo06 { public static void main(String[] args) throws IOException {
FileInputStream fis = new FileInputStream("C:\\Users\\zr\\Pictures\\截图\\winC.PNG");
BufferedInputStream bis = new BufferedInputStream(fis);
FileOutputStream fos = new FileOutputStream("D:\\c.PNG");
BufferedOutputStream bos = new BufferedOutputStream(fos);
byte[] buffer = new byte[1024];
int len = 0;
long begin = System.currentTimeMillis();
while ((len=bis.read(buffer))!=-1){
bos.write(buffer,0,len);
}
long end = System.currentTimeMillis();
System.out.println(end-begin);
bos.close();
fos.close();
bis.close();
fis.close();
}
}
以上是 Java基础总结 的全部内容, 来源链接: utcz.com/z/394663.html