文章目录
1.如何更好更高效的学习Java?
- 多写(代码),多写(笔记),多写(文章)
- 多练(交流),多练(思维),多练(技能)
- 多分享(知识),多提问(怎么了),多思考(为什么)
- 最重要(坚持)没有人能随随便便成功
2.预科
2.1 什么是计算机?
计算机由硬件和软件组成,是鞥狗按照程序运行,自动、高速处理海量数据的现代化智能电子设备。计算机广泛应用在:科学计算,数据处理,自动控制,计算机辅助设计,人工智能,网络等领域。
2.2 计算机硬件
一些物理装置按照系统结构的要求构造成一个有机整体为计算机软件提供物质基础。
2.3 冯诺依曼体系结构
2.4 计算机软件
- 计算机软件可以使计算机按照事先预定好的顺序弯沉个特定的功能
- 计算机软件按照其功能划分为系统软件与应用软件
2.4.1 常用的dos命令
#盘符切换
#查看当前目录下的所有文件 dir
#切换目录 cd change directory
#切换到上一级 cd ..
#清理屏幕 cls(clear screen)
#退出终端
#查看电脑的ip ipconfig
#打开应用
calc
mspaint
notepad
#ping
2.5 计算机语言发展史
- 第一代语言:机器语言
我们都知道计算机的基本计算方式都是基于二进制的方式
- 第二代语言:汇编语言
解决人类无法读懂机器语言的问题,指令代替二进制
- 第三代语言
摩尔定律:当价格不变时,集成电路上可容纳的晶体管数目,大约每隔18个月便会增加一倍,性能也将提升一倍。换言之,每一美元所能买到电脑性能,将每隔18个月翻两倍以上。
- 高级语言,大体上分为:面向过程和面向对象两大类。
- C语言是典型的面向郭晨给的语言。
- C++、Java是典型的面向对象的语言
3. Java帝国的诞生
3.1 C & C++
1972年C诞生,特点:
1.贴近硬件,运行极快,效率极高。
2.操作系统,编译器,数据库,网络系统等
3.指针和内存管理
1982年C++诞生,特点:
1.面向对象
2.兼容C
3.图形领域、游戏等。
3.2 反抗
我们要建立一个新语言:
- 语法有些像C
- 没有指针
- 没有内存管理
- 真正的可移植性,编写一次,到处运行
- 面向对象
- 类型安全
- 高质量的类库
三高:高可用,高性能,高并发
3.3 Java的特性和优势
简单性、面向对象、可移植性、高性能、分布式、动态性(反射机制)、多线程(带来更好的交互行为)、安全性、健壮性
思考:Java为什么能够成功?
3.4 Java三大版本
- JavaSE:标准版(桌面程序,控制台开发)
JavaME:嵌入式开发- JavaEE:企业级开发(web端,服务器开发)
3.5 JDK、JRE、JVM
- JDK:Java Development Kit (JDK包含JRE)
- JRE:Java Runtime Environment (运行时环境)
- JVM : JAVA Virtual Machine (java虚拟机)
3.6 Java开发环境搭建
- JDK下载与安装
- 配置环境变脸
- JDK安装目录
- Hello World以及简单的语法规则
- Notepad++安装和使用
3.7 写一个Hello World
- 随便新建一个文件夹,存放代码
- 新建一个java文件
文件后缀名为.java
Hello.java
注意点:系统可能没有显示文件的后缀名,我们需要手动打开
- 编写代码
public class Hello{
public static void main(String[] args){
System.out.print("Hello World!");
}
}
- 编译javac java文件,会生成一个class文件
- 运行class文件,java class文件
可能会遇到的情况
- 每个单词的大小不能出现问题,java是大小写敏感的
- 尽量使用英文
- 文件名和类名必须一致,并且首字母大写
- 符号使用了中文
3.8 java程序运行机制
- 编译型
- 解释型
4. Java基础语法
4.1 注释、标识符、关键字
4.1.1 注释
java中的注释有三种:1.单行注释 2.多行注释 3.文档注释
4.1.2 标识符
关键字
java所有的组成部分都需要名字。类名、变量名以及方法名都被称之为标识符。
标识符注意点
- 所有标识符都应该以字母(A-Z或者a-z),美元符($)或者下划线(_)开始
- 首字符之后可以是字母,美元符,下划线或者数字的任何字符组合
- 不能使用关键字作为变量名或者方法名
- 标识符是大小写敏感的
- 合法的标识符举例:age、_value
- 可以使用中文命名,但是一般不建议这样去使用,也不建议使用拼音,很low
4.1.3 数据类型
- 强类型语言
要求变量的使用严格符合规定,所有的变量都必须先定义后才可以使用 - 弱类型语言
3.Java的数据类型分为两大类
- 基本类型
- 引用类型
除了基本数据类型之外都是引用类型
public class test2 {
public static void main(String[] args) {
//八大基本数据类型
//整数
int num1 = 10; //最常用
byte num2 = 20;
short num3 = 30;
long num4 = 30L; //Long类型要在数字后面加一个L
//小数:浮点数
float num5 = 50.1F; //加一个F表示这是一个float类型
double num6 = 3.1415926535;
//字符
char name1 = 'A';
//字符串,String不是关键字,类
//String name = "秦疆";
//布尔值
boolean a = false;
boolean b = true;
}
}
4.1.4 什么是字节?
- 位(bit):是计算机内部数据储存的最小单位,11001100是一个八位二进制数
- 字节(byte):是计算机中数据处理的基本单位,习惯上用B来表示
- 1B = 8bit
- 字符:是指计算机中使用的字母、数字、字和符号
思考:电脑的32位和64位的区别是什么呢?
1bit表示一位
1Byte表示一个字节,1B = 8b
1024B = 1Kb
1024KB = 1M
1024M = 1G
数据类型扩展以及面试
public class Demo2 {
public static void main(String[] args) {
//整数拓展: 进制 二进制0b 十进制 八进制0 十六进制0x
int i =10;
int i2 = 010; //八进制0
int i3 = 0x10;//十六进制0x 0~9 A~F 16
//=================================================
//浮点数拓展?银行业务怎么表示?钱
//BigDecimal 数学工具类
//float 有限 离散 舍入误差 大约 接近但不等于
//double
//最好完全使用浮点数进行比较!!!
float f = 0.1f;//0.1
double d = 1.0/10; //0.1
System.out.println(f==d);//false
float d1 = 2312312312312312321f;
float d2 = d1 + 1;
System.out.println(d1 == d2);//true
System.out.println("====================================================");
char c1 = 'a';
char c2 = '中';
System.out.println(c1);
System.out.println((int)c1);
System.out.println(c2);
System.out.println((int)c2);
//所有的字符本质还是数字
//编码 Unicode 表: 97 = a 2字节 65536 Excel 2 16 = 65536
//U0000 UFFFF
char c3 = '\u0061';//转义
System.out.println(c3);
//转义字符
// \t 制表符
// \n 换行
System.out.println("hello\tworld");
System.out.println("====================================================");
String sa = new String("hello world");
String sb = new String("hello world");
System.out.println(sa == sb);
String sc = "hello world";
String sd = "hello world";
System.out.println(sc == sd);
//对象从内存分析
//布尔值扩展
boolean flag = true;
if(flag == true){}//新手
if(flag){}//老手
//less is more!代码要精简
}
}
4.1.4 类型转换
由于java是强类型的语言,所以要进行有些运算的时候需要强类型转换。
public class Demo3 {
public static void main(String[] args) {
int i = 128;
byte b = (byte)i; //内存溢出
//强制转换 (类型)变量名 高--低
//自动转换 低--高
System.out.println(i);
System.out.println(b);
/*
注意点:
1.不能对布尔值进行转换
2.不能把对象类型转换为不相干的类型
3.在把高容量转换到低容量的时候,强制转换
4.转换的时候可能存在内存溢出,或者精度问题
*/
System.out.println("=====================================");
System.out.println((int)23.7);//23
System.out.println((int)-45.89f);//-45
System.out.println("=====================================");
char c = 'a';
int d = c + 1;
System.out.println(d);
System.out.println((char)d);
}
}
public class Demo4 {
public static void main(String[] args) {
//操作比较大的数的时候,注意溢出问题
//JDK7新特性,数字之间可以用下划线分割
int money = 10_0000_0000;
int years = 20;
int total = money * years;//计算的时候溢出了
long total2 = money*years;//默认是int,转换之前已经存在问题了
long total3 = money * ((long)years);//先把一个数转换为Long
System.out.println(total3);
}
}
4.1.5 运算符
java语言支持一下的运算符:
算数运算符:+,-,*,/,%,++,--
赋值运算符:=
关系运算符:>,<,>=,<=,==,!=instanceof
逻辑运算符:&&,||,!
位运算符:&,|,^,~,>>,<<,>>>
条件运算符?:
扩展赋值运算符:+=,-=,*=,/=
package operator;
public class Demo04 {
public static void main(String[] args) {
// ++ -- 自增 自减 一元运算符
int a = 3;
int b = a++; //执行完这行代码后,先给b赋值,再自增
//a = a + 1;
System.out.println(a);
//a = a + 1;
int c = ++a; //执行完这行代码前,先自增,再给b赋值
System.out.println(a);
System.out.println(b);
System.out.println(c);
//幂运算 2^3 2*2*2 = 8
double pow = Math.pow(3,2);
System.out.println(pow);
}
}
package com.kuang.base;
public class Demo3 {
public static void main(String[] args) {
int i = 128;
byte b = (byte)i; //内存溢出
//强制转换 (类型)变量名 高--低
//自动转换 低--高
System.out.println(i);
System.out.println(b);
/*
注意点:
1.不能对布尔值进行转换
2.不能把对象类型转换为不相干的类型
3.在把高容量转换到低容量的时候,强制转换
4.转换的时候可能存在内存溢出,或者精度问题
*/
System.out.println("=====================================");
System.out.println((int)23.7);//23
System.out.println((int)-45.89f);//-45
System.out.println("=====================================");
char c = 'a';
int d = c + 1;
System.out.println(d);
System.out.println((char)d);
}
}
package operator;
public class Demo06 {
/**
A = 0011 1100
B = 0000 1101
-------------------
A & B 0000 1100
A | B 00111101 如果对应位都是0则为0,否则为1
A ^ B = 0011 0001 对应位相同则为0,否则就为1 ,异或
~B = 1111 0010
2 * 8 = 16 2*2*2*2
<< *2 左移相当于乘2
>> /2 右移相当于除2
0000 0000 0
0000 0001 1
0000 0010 2
0000 0011 3
*/
public static void main(String[] args) {
System.out.println(2<<3);
}
}
public class Demo07 {
public static void main(String[] args) {
int a = 10;
int b = 20;
a+=b;
a-=b;
System.out.println(a);
System.out.println(""+a+b);
System.out.println(a + b+"");
}
}
public class Demo08 {
public static void main(String[] args) {
// x ? y : z
//如果x == truw ,则结果为y,否则结果为z
int score = 80;
String type = score < 60 ? "不及格" : "及格";// 必须掌握
//if
System.out.println(type);
}
}
4.1.6 包机制
为了更好的组织类,java提供了包机制,用于区别类名的命名空间
一般利用公司域名倒置作为包名
4.1.7 java流程控制
4.1.7.1 用户交互Scanner
之前我们学的基本语法中我们并没有实现程序和人的交互,但是Java给我们提供了这样的一个工具类,我们可以获取用户的输入,java.util.Scanner是java5的新特性,我们可以通过Scanner类来获取用户的输入。
基本语法:
Scanner s = new Scanner(System.in);
import java.util.Scanner;
public class Demo05 {
public static void main(String[] args) {
//创建一个扫描器对象,用于接收键盘数据
Scanner sc = new Scanner(System.in);
System.out.println("使用next方式接收:");
//判断用户有没有输入字符串
if(sc.hasNext()){
String str = sc.next();
System.out.println("输出的内容:"+ str);
}
//凡是属于IO流的类如果不关闭会一直占用资源,要养成好习惯用完就关掉
sc.close();
}
}
import java.util.Scanner;
public class Demo06
{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
System.out.println("请输入数据:");
String str = sc.nextLine();
System.out.println("输入的内容为:"+str);
sc.close();
}
}
import java.util.Scanner;
public class Demo07 {
public static void main(String[] args) {
//我们可以输入多个数字,并求其总和与平均数,每输入一个数字用回车确认,通过输入非数字来结束输入并输出执行结果
Scanner scanner = new Scanner(System.in);
//和
double sum = 0;
int m = 0;
//通过循环判断是否还有输入,并在里面对每一次进行求和和统计
while(scanner.hasNextDouble()){
double x = scanner.nextDouble();
m++;
sum = sum + x;
System.out.println("你输入了第" +m + "个数据,然后当前结果sum ="+ sum);
}
System.out.println(m + "个数的和为:" + sum);
System.out.println(m + "个数的平均值是:" + (sum / m));
scanner.close();
}
}
5. java方法详解
5.1 何谓方法?
System.out.println(),那么它是什么?
Java方法是语句的集合,它们在一起执行一个功能。
- 方法是解决一类问题的步骤的有序组合
- 方法包含于类或者对象中
- 方法在程序中被创建,在其他地方被引用
设计方法的原则:方法的本意是功能块,就是实现某个功能的语句块的集合。我们设计方法的时候,最好保持方法的原子性,就是一个方法只完成1个功能,这样有利于我们后期的扩展。
5.2 方法的定义
Java的方法类似于其他语言的函数,是一段用来完成特定功能的代码片段,一般情况下,定义一个方法包含以下语法:
方法包含一个方法头和一个方法体,下面是一个方法的所有部分:
- 修饰符:这是可选的,告诉编译器如何调用该方法,定义了该方法的访问类型。
- 返回值类型:方法可能会返回值。
- 方法名
- 参数类型:形参与实参
- 方法体:方法体包含具体的语句,定义该方法的功能
public class Demo08 {
public static void main(String[] args) {
//实际参数:实际调用传递给他的参数
int sum = add(1,2);
System.out.println(sum);
}
//加法
//形式参数,用来定义作用的
public static int add(int a, int b ){
return a + b;
}
}
5.3 方法调用
调用方法:对象名.方法(实参列表)
java支持两种调用方法的方式,根据方法是否返回值来选择。
当方法返回一个值的时候,方法调用通常被当做一个值。例如:
int larger = max(30,40);
如果方法的返回值是void,方法调用一定是一条语句。
System.out.println("Hello,kuangshen");
public class Demo09 {
public static void main(String[] args) {
int max = max(10,20);
System.out.println(max);
}
//比大小
public static int max(int num1,int num2){
int result = 0;
if(num1 == num2){
System.out.println("num1 == num2");
return 0;
}
if(num1 > num2){
result = num1;
}else{
result = num2;
}
return result;
}
}
课后拓展:值传递(Java)和引用传递
5.3 方法的重载
- 重载就是在一个类中,有相同的函数名称,但形参不同的函数。
方法重载的规则:
- 方法名称必须相同。
- 参数列表必须不同(个数不同、类型不同、参数排列顺序不同等)
- 方法的返回类型可以相同也可以不同
- 仅仅返回类型不同不足以称为方法的重载。
实现理论: 方法名称相同的时候,编译器会根据调用方法的参数个数、参数类型等去逐个的匹配以选择对应的方法,如果匹配失败,则编译器报错。
5.4 命令行传参
有时候你希望运行一个程序时候再传递给它消息。这要靠传递命令行参数给main()函数实现。
public class Demo03 {
public static void main(String[] args) {
//args.length 数组长度
for(int i = 0; i < args.length; i++){
System.out.println("args["+ i + "]:" +args[i]);
}
}
}
5.5 可变参数
- JDK1.5开始,java支持传递同类型的可变参数给一个方法
- 在方法的生命中,在指定参数类型后加一个省略号(…)
- 一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。任何普通的参数必须在它之前声明。
public class Demo10 {
public static void main(String[] args) {
Demo10 demo10 = new Demo10();
demo10.test(1,2,2,3);
}
public void test(int ...i){
System.out.println(i[1]);
}
}
5.6 递归(重要)
- A方法调用B方法,我们很容易理解
- 递归就是:A方法调用A方法!就是自己调自己
- 利用递归可以用简单的程序来解决一些复杂的问题。它通常把一个大型复杂的问题层层转化为一个与原问题相似的规模较小的问题来求解,递归策略只需要少量的程序就可以描述出解题过程所需要的多次重复计算,大大减少程序的代码量。递归的能力在于用优先的语句来定义对象的无限集合。
递归结构包括两个部分:
递归头:什么时候不调用自身方法,如果没有头,将陷入死循环。
递归体:什么时候需要调用自身方法
public class Demo12 {
public static void main(String[] args) {
System.out.println(f(5));
}
//1! 1
//2! 2*1
//5! 5*4*3*2*!
public static int f(int n ){
if(n ==1){
return 1;
}else{
return n * f(n -1);
}
}
}
边界条件:边界
前阶段:
返回阶段 n*(n -1)
栈
作业:写一个计算器,要求实现加减乘除功能,并且能够循环接受新的数据,通过用户交互实现
思路推荐:
写四个方法:加减乘除
利用循环+switch进行用户交互
传递需要操作的两个数
输出结果
5.7 数组
- 数组是相同数据类型的有序集合
- 数组描述的是相同类型的若干个数据,按照一定的先后次序排列组合而成
- 其中,每一个数据称作一个数组元素,每个数组元素可以通过一个下标来访问
5.7.1 数组创建
5.7.2 内存分析
Java内存分析:
- 堆:存放new的对象;可以被所有的线程共享,不会存放别的对象引用
- 栈:存放基本的变量类型(会包含这个基本类型的具体数值);引用对象的变量(会存档这个引用在堆里面的具体地址)
- 方法去:可以被所有的线程共享;包含了所有的class和static变量
5.7.3 三种初始化
public class Demo14 {
public static void main(String[] args) {
//静态初始化:创建+赋值
int[] a = {1,2,3,4,5,6,7,8};
System.out.println(a[0]);
//动态初始化:包含默认初始化
int[]b = new int[10];
b[0] = 10;
System.out.println(b[0]);
}
}
**
数组的默认初始化:数组是引用类型,它的元素相当于类的实例变量,因此数组一经分配空间,其中每个元素也被按照实例变量同样的方式被隐式初始化。
5.7.4 数组的基本特点
- 其长度是确定的,数组一旦被创建,它的大小就是不可以改变的
- 其元素必须是相同的类型,不允许出现混合类型
- 数组的元素可以是任何数据类型,包括基本类型和引用类型
- 数组变量属于引用类型,数组也可以看成对象,数组中的每一个元素相当于该对象的成员变量。数组本身就是对象,java中对象是在堆中的,因此数组无论保存原始类型还是其他的对象类型,数组对象本身是在堆中的。
5.7.5 数组边界
下标的合法区间:【0,length-1】 如果越界就会发生异常,ArrayIndexOutOfBoundsException
小结:
- 数组是相同数据类型的有序集合
- 数组也是对象,数组元素相当于对象的成员变量
- 数组长度是确定的,不可变的,如果越界,就会报异常
5.7.6 数组的使用
public class Demo15 {
public static void main(String[] args) {
int[] arrays = {1,2,3,4,5};
//打印全部的数组元素
for(int i = 0 ; i < arrays.length;i++){
System.out.println(arrays[i]);
}
System.out.println("======================");
int sum = 0;
//计算所有元素的和
for(int i = 0; i < arrays.length; i++){
sum += arrays[i];
}
System.out.println("sum = " + sum);
System.out.println("======================");
//查找最大元素
int max = arrays[0];
for(int i = 1; i<arrays.length; i++){
if(arrays[i] > max){
max = arrays[i];
}
}
System.out.println(max);
}
}
public class Demo16 {
public static void main(String[] args) {
int[]arrays = {1,2,3,4,5};
//JDK1.5 没有下标
// for(int array : arrays){
// System.out.println(array);
// }
// printArray(arrays);
int[] reverse = reverse(arrays);
printArray(reverse);
}
//打印数组元素
public static void printArray(int[] arrays){
for(int i = 0; i < arrays.length; i++){
System.out.println(arrays[i] + "");
}
}
//反转数组
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;
}
}
5.7.7 多维数组
多维数组可以看成数组的数组。
public class Demo17 {
public static void main(String[] args) {
//[4][2]
/*
1,2 array[0]
2,3 array[1]
3,4 array[2]
4,5 array[3]
*/
int[][]array = {{1,2},{2,3},{3,4},{4,5}};
System.out.println(array[0][0]);
System.out.println(array[0][1]);
for (int i = 0; i < array.length ; i++) {
for (int j = 0; j < array[i].length ; j++) {
System.out.print(array[i][j]);
}
}
}
}
5.7.8 Arrays类
- 数组的工具类 java.util.Arrays
- 由于数组对象本身并没有什么方法可以供我们使用,但是API中提供了一个工具类Arrays供我们使用,从而可以对数据对象进行一些基本的操作
- 查看JDK文档
- Arrays类中放大都是static修饰的静态方法,在使用的时候可以直接使用类名进行调用,而不用使用对象来调用
具有以下的功能:
给数组赋值 :fill
对数组排序 :通过sort方法,按升序
比较数组 :通过equals方法比较数组中元素值是否相等
查找数组元素:通过binarySearch方法对排序好的数组进行二分查找法操作
import java.util.Arrays;
public class Demo17 {
public static void main(String[] args) {
int[] a = {1,2,3,4,9090,3123,23241,23,22};
System.out.println(a); //[I@1b6d3586 hashcode
//打印数组元素 Arrays.toString
//System.out.println(Arrays.toString(a));
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.println(a[i] + "]");
}else{
System.out.print(a[i]+ ", ");
}
}
}
}
6.冒泡排序
- 总共有八大排序,总共有八大排序
- 冒泡的代码是相当简单的,两层循环,外层冒泡轮数,里层依次比较,江湖中人人尽皆知。
package com.kuang.base;
import java.util.Arrays;
//冒泡排序(O(n2))
//1.比较数组中,两个相邻的元素,如果第一个数比第二个数大,就交换他们的位置
//2.每一次比较都会产生出一个最大或者最小的数字
//3.下一轮则可以少一次排序
//4.依次循环,直到结束!
public class Demo18 {
public static void main(String[] args) {
int[]a = {1,2,3,4,25,45,44,7};
int[]sort = sort(a);//调用完我们自己写的排序方法后,但会一个排序的数组
System.out.println(Arrays.toString(sort));
}
public static int[] sort(int[] array){
//外层循环,判断我们这个要走多少次
//临时变量
int temp = 0;
for (int i = 0; i < array.length - 1; i++) {
//内层循环,比较判断两个数,如果第一个数比第二个数,则交换位置
for (int j = 0; j < array.length - 1; j++) {
if(array[j + 1] > array[j]){
temp = array[j];
array[j] = array[j + 1];
array[j + 1] = temp;
}
}
}
return array;
}
}
7.稀疏数组
public class Demo19 {
public static void main(String[] args) {
//1.创建一个二维数组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);
//2.创建一个稀疏数组的数组
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];
}
}
}
for (int i = 0; i < array2.length; i++) {
System.out.println(array2[i][0]+"\t"
+array2[i][1] + "\t"
+array2[i][2] + "\t");
}
System.out.println("====================================");
System.out.println("还原");
//1.读取稀疏数组
int[][] array3 = new int[array2[0][0]][array2[0][1]];
//2.给其中的元素还原它的值
for (int i = 1; i < array2.length; i++) {
array3[array2[i][0]][array2[i][1]] = array2[i][2];
}
//3.打印
System.out.println("输出还原的数组");
for(int[] ints : array1){
for (int anInt : ints) {
System.out.print(anInt + "\t");
}
System.out.println();
}
}
}
8.面向对象编程OOP
8.1 面向过程 & 面向对象
面向过程思想:
- 步骤清晰简单,第一步做什么,第二步做什么
- 面对过程适合处理一些较为简单的问题
面向对象思想:
- 物以类聚,分类的思维模式,思考问题首先会解决问题需要哪些分类,然后对这些分类进行单独思考。最后才对某个分类下的细节进行面向过程思索。
- 面向对象适合处理复杂的问题,适合处理需要多人协作的问题!
对于描述复杂的事务,为了宏观上把握,从整体上合理分析,我们需要使用面向对象的思路来分析整个系统。但是具体到微观的凑在哦,仍然需要面向过程的思路去处理。
8.2 什么是面向对象
面向对象编程
面向对象编程的本质是:以类的方式去组织代码,以对象的组织数据
抽象(把像的部分抽出来)
三大特性:
- 封装
- 继承
- 多态
从认识论的角度考虑先有对象后有类。对象,是具体的事务。类,是抽象的,是对对象的抽象。
从代码运行角度考虑是先有类后又对象。类是对象的模板
8.3 回顾方法的定义
方法的定义:
修饰符
返回类型
break:跳出switch,结束循环和return的区别
方法名:注意规范就ok 见名知义
参数列表
异常抛出
方法的调用:
静态方法
非静态方法
形参和实参
值传递和引用传递
this关键字
//值传递
public class Demo04 {
public static void main(String[] args) {
int a = 1;
System.out.println(a);
Demo04.change(a);
System.out.println(a);
}
//返回值为空
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);
}
public static void change(Person person){
//person是一个对象:指向的是Person这个类 Person person = new Person();这是一个具体的人可以改变属性
person.name = "秦疆";
}
}
//定义一个Person类,有一个属性:name
class Person{
String name;
}
8.4 类与对象的关系
- 类是一种抽象的数据类型,它是对一类事物整体描述/定义,但这并不能代表某一个具体的事物
- 对象是抽象概念的具体实例
//java --> class
public class Person {
//一个类即使什么都不写,它也会存在一个方法
//显示的定义构造器
String name;
//实例化初始值
//1.使用new关键字,本质是在调用构造器
//2.用来初始化值
public Person() {
}
public Person(String name) {
this.name = name;
}
//alt+insert
}
/*
public static void main(String[] args) {
//类: 抽象的,实例化
//类实例化后会返回一个自己的对象
//student对象就是一个Student类的具体实例
//Student student = new Student();
//new 实例化一个对象
Person person = new Person();
System.out.println(person.name);
构造器:
1.和类名相同
2.没有返回值
作用:
1.new本质在调用构造方法
2.初始化对象的值
注意点:
1.定义有参构造只好,如果想使用无参构造,显示的定义一个无参的构造
alt+insert
*/
8.5 内存分析
package com.kuang;
import com.kuang.base3.Pet;
public class Application {
public static void main(String[] args) {
Pet dog = new Pet();
dog.name = "旺财";
dog.age = 3;
dog.shout();
System.out.println(dog.name);
System.out.println(dog.age);
Pet cat = new Pet();
}
}
public class Pet {
public String name;
public int age;
//无参构造
public void shout(){
System.out.println("叫了一声");
}
}
8.6 小结
1.类与对象
类是一个模板:抽象,对象是一个具体的实例
2.方法
定义,调用!
3.对应的引用
引用类型 基本类型(8)
对象是通过引用来操作的:栈-->堆
4.属性:字段Field 成员变量
默认初始化:
数字:0 0.0
char: u0000
boolean: false
引用:null
修饰符 属性类型 属性名 = 属性值!
5.对象的创建和使用
-必须使用new关键字创建对象,构造器 Person kuangshen = new Person();
-对象的属性 kuangshen.name
-对象的方法 kuangshen.sleep()
6.类
静态的属性 属性
动态的行为 方法
封装、继承、多态
8.7 封装
- 该露的露,该藏的藏
- 我们程序的设计要追求“高内聚,低耦合”。高内聚就是类的内部数据操作细节自己完成,不允许外部干涉;低耦合:仅暴露少量的方法给外部使用。
封装(数据的隐藏) 通常,应禁止直接访问一个对象中数据
8.8 继承
8.9 Super
私有的东西无法被继承,super()调用父类的构造器必须要放在子类构造器的第一行
super总结:
- super调用父类的构造方法,必须在构造方法的第一个
- super必须只能出现在子类的方法或者构造方法中!
- super和this不能同时调用构造方法!
VS this:
代表的对象不同:
-
this:本身调用者这个对象
-
super:代表父类对象的应用
前提:
- this:没有继承也可以使用
- super只能在继承条件的时候才可以使用
构造方法
- this() 本类的构造
- super():父类的构造!
8.10 重写
import com.kuang.base5.Student;
import com.kuang.base6.A;
import com.kuang.base6.B;
public class Application {
//静态方法和费静态的方法区别很大!
//静态方法
//非静态:重写
public static void main(String[] args) {
//方法的调用只和左边,定义的数据类型有关
A a = new A();
a.test();//A
B b = new A(); //子类重写了父类的方法,非静态方法重写了父类的方法!
b.test();//B
}
}
/*
重写:需要有继承关系,而且是子类重写父类的方法!
1.方法名必须要相同
2.参数的列表必须相同
3.修饰符:范围可以被扩大:public > Protected > Default > private
4.抛出的异常:范围可以被缩小但不能扩大!ClassNotFoundException --> Exception(大)
重写,子类的方法和父类必须要一致,方法体不同!
为什么需要重写?1.父类的功能子类不一定需要或者不一定满足!
Alt + insert : Override
*/
8.11 多态
package com.kuang.base7;
public class Person {
public void run(){
System.out.println("run");
}
}
/*
多态注意事项:
1.多态是方法的多态,属性没有多态
2.父类和子类,有联系 类型转换异常! ClassCastException!
3.多态存在条件:继承关系,方法需要重写,父类的引用指向子类对象! Father f1 = new Son();
1.static 方法属于类,不属于实例,不能被重写
2.final 常量池
3.private方法 没有办法重写
*/
public class Student extends Person{
@Override
public void run() {
System.out.println("son");
}
public void eat(){
System.out.println("ear");
}
}
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();
//对象能执行哪些方法,主要看对象左边的类型,和右边关系不大!
((Student)s2).eat(); //子类重写了父类的方法,执行子类的方法
s1.run();//
}
}
instanceof
package com.kuang.base7;
public class Application {
public static void main(String[] args) {
//Object > Person > Student
//Object > Person > Teacher
Object object = new Student();
//System.out.println(X instanceof Y);//能不能编译通过,要看X和Y是否存在父子关系
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
}
}
package com.kuang.base7;
public class Application {
public static void main(String[] args) {
//类型之间的转化:父 子
//子类转换为父类,可能丢失自己的本来的一些方法
Student student = new Student();
student.go();
Person person = student;
}
}
/*
1.父类引用指向子类的对象
2.把子类转换为父类,向上转型;
3.把父类转换为子类,向下转型:强制转换
4.方便方法的调用,减少重复的代码!简洁
核心抽象的思想:封装、继承、多态! 抽象类,接口
*/
8.12 static关键字详解
package com.kuang.base8;
public class Person {
{
//2
//代码块(匿名代码块)
System.out.println("匿名代码块");
}
//1
static{
//静态代码块
System.out.println("静态代码块");
}
//3
public Person(){
System.out.println("构造方法");
}
public static void main(String[] args) {
Person person1 = new Person();
}
}
9.抽象类和接口
9.1 抽象类
package com.kuang.base9;
//abstract抽象类:类extends:单继承~(接口可以多继承) 插座~
public abstract class Action {
//约束~有人帮我们实现
//abstract,抽象方法,只有方法名字,没有方法的实现!
public abstract void doSomething();
//1.不能new这个抽象类,只能靠子类去实现它,约束
//2.抽象方法可以写普通的方法
//3.抽象方法必须在抽象类中
//抽象的抽象:约束~
//思考题? new,存在构造器么?
//存在的意义 抽象出来~ 提高开发效率,可拓展性比较高
}
9.2 接口
- 普通类:只有具体实现
- 抽象类:具体实现和规范(抽象方法)都有!
- 接口:只有规范!自己无法写方法专业的约束!约束和实现分离:面向接口编程
- 接口就是规范,定义的是一组规则,体现了现实世界中“如果你是…则你必须能…”的思想。如果你是天使,则必须能飞。如果你是汽车,则必须能跑。
- 接口的本质是契约,就像我们人间的法律一样。制定好后大家去遵守。
- OO的精髓,是对对象的抽象,最能体现这一点的就是接口。为什么我们讨论设计模式都只针对具备了抽象能力的语言(比如C++、java、C#等),就是因为设计模式锁研究的,实际上就是如何合理的去抽象。
声明类的关键字是class,声明接口的关键字是interface
package com.kuang.base10;
//抽象的思维~Java
//interface 定义的关键字,接口都需要有实现类
public interface UserService {
//接口中所有定义其实都是抽象的 public abstract
//常量~public static final
int AGE = 99;
void run(String name);
void delete(String name);
void update(String name);
void query(String name);
}
作用:
1.约束
2.定义一些方法,让不同的人实现~ 10 —> 1
3.public abstract
4.public static final
5.接口是不能被实例化,接口中没有构造方法
6.implements可以实现多个接口
7.必须要重写接口中的方法
8.总结博客
10.内部类
package com.kuang.base11;
public class Outer {
private int id;
public void out(){
System.out.println("这是外部类的方法");
}
public class Inner{
public void in(){
System.out.println("这是内部类的方法");
}
//获得外部类的私有属性
public void getID(){
System.out.println(id);
}
}
}
11.异常
11.1异常处理机制
- 抛出异常
- 捕获异常
异常处理五个关键字:
- try、catch、finally、throw、throws
package com.kuang.exception;
public class Test {
public static void main(String[] args) {
int a = 1;
int b = 0;
try {//try监控区域
System.out.println(a/b);
}catch(ArithmeticException e){//catch捕获异常
System.out.println("程序出现异常,变量b不能为0");
}finally {
System.out.println("finally");
}
}
}
package com.kuang.exception;
public class Test {
public static void main(String[] args) {
int a = 1;
int b = 0;
//假设要捕获多个异常:从小到大捕获!
try {//try监控区域
if(b ==0 ){
throw new ArithmeticException();//主动的抛出异常,一般在方法中使用
}
System.out.println(a/b);
new Test().a();
}catch(Error e){//catch(想要捕获的异常类型)捕获异常
System.out.println("程序出现异常,变量b不能为0");
}catch(Exception e){
System.out.println("Exception");
}catch(Throwable t){
System.out.println("Throwable");
}finally {
System.out.println("finally");
}
//finally 可以不要finally 假设IO,资源,关闭!
}
public void a(){b();}
public void b(){a();}
}
package com.kuang.exception1;
public class Test {
static void test(int a)throws MyException{
if(a > 10){
throw new MyException(a);//抛出
}
System.out.println("ok");
}
public static void main(String[] args) {
try {
test(1);
} catch (MyException e) {
System.out.println("MyException=>"+e);
}
}
}