一、前言
常用的DOS命令
#盘符切换
#查看当前目录下所有文件 dir
#切换目录 cd directory,通过/d可以实现盘符之间的切换
eg.E:\>cd /d f:\IDE /*原来在E盘,切换到D盘的IDE文件*/
#清理屏幕 cls
#退出终端exit
#查看电脑IP ipconfig
#打开应用 计算器calc 画图mspaint 记事本notepad
#ping 命令
#文件操作命令
#创建目录 md
#删除目录 rd
#新建文件 cd>a.txt
#删除文件 del a.txt
二、java入门
1. Java三大版本
javaSE 标准版
javaME 嵌入式开发
javaEE E企业级开发
2. JDK JRE JVM
JDK: java开发者工具,包含所有
JRE: java运行时环境,包含Java虚拟机
JVM: java虚拟机
3. 开发环境的搭建
如何卸载JDK
1.删除java安装目录
2.删除Java_HOME
3.删除path下关于Java的目录
4.在命令行窗口输入java -version
安装JDK
4. HelloWorld
1.新建文件夹,存放代码
2.新建Java文件
文件后缀名为.java
eg. Hello.java
3.编写代码
public class Hello{ //类 public class
public static void main(String[] args){ //方法 main
System.out.print("Hello,World!");
}
}
4.编译 javac java文件 (在该代码的目录下,文件后缀.java),生成.class文件
5. 运行class文件 java class文件
注意点:
1.单词的大小写敏感
2.尽量使用英文
3.文件名 和类名 必须保证一致
4.符号使用英文,分号
三、java基础
1. 注释、标识符、关键字
1.1 注释
单行注释 //内容//
多行注释 /* …
…*/
JavaDoc:文档注释 /**
*@…
*@…
*/
1.2 标识符
2. 数据类型
2.1 基本类型
//八大基本数据类型
//整数
int num1 = 10; //最常用
byte num2 = 20;
short num3 = 30;
long num4 = 30L;//long类型 要在后面加L
//小数:浮点数
float num5 = 40.05F;//float类型 要在后面加F
double num6 = 3.1415927;
//字符
char name = '山';
//字符串,String不是关键字,是一个类
//String namea = "david";
//布尔值
boolean flag = true;
数据类型扩展以及面试题讲解
整数拓展:进制
二进制0b 十进制 八进制0 十六进制0x
浮点数拓展:
在处理银行类业务时,要完全避免使用浮点型数据进行比较,因为他是有限离散的,
可以使用BigDecimal 这种数学工具类来代替
布尔值拓展
boolean flag = true;
if (flag ==true){ } //等于if (flag) { }
转义字符
\t :制表符 相当于tab
\n :换行
...
3. 类型转换
运算中,不同类型的数据要先转化同一类型,然后进行运算
byte的最大值只到127,出现了内存溢出
强制转换的格式:(类型)变量名 高到低
自动转换 低到高
类型转换的注意点:
1.不能对布尔值进行转换
2.不能把对象类型转化为不相干类型
3.在把高容量转化为低容量时需要强制转换,反之可以自动转换没有问题
4.转换时需要考虑内存溢出或者精度问题
常见问题:
4. 变量
public class HelloWorld {
public static void main(String[] args) {
int a; //基本类型
char x ='X';
double pi = 3.14;
String name = "cici",//引用类型 String
}
}
变量的作用域:
public class HelloWorld { //整个class是一个类
//属性:变量
//类变量 static
static double salary = 2500;
//实例变量 在类里面,方法外面,从属于对象(类),如果不进行初始化,默认是0,0.00
//布尔值:默认是false
//除了基本类型,其余的都是NULL
String name;
int age;//age没有赋初值,默认值
public static void main(String[] args) { //main方法,在类里面
int num1 = 10; //局部变量,必须申明和初始化值
System.out.println(i);
//变量类型 变量名字 = new HelloWorld();
HelloWorld hello = new HelloWorld();
System.out.println(hello.age); //结果输出为0
System.out.println(hello.name);//输出NULL
//类变量 static
System.out.println(salary);
}
//其他方法
public void add(){
}
}
5. 常量
初始化之后不能变动
final 常量名 = 值; 常量名通常为大写
public class HelloWorld {
//修饰符,不区分前后 static final 和final static 结果一样
staic final double PI =3.14;
public static void main(String[] args) {
System.out.println(PI);
}
}
变量的命名规范
6. 基本运算符
public class Demo01 {
public static void main(String[] args) {
//二元运算符
//Ctrl+D :复制当前行到下一行
int a = 10;
int b = 20;
int c = 25;
int d = 25;
System.out.println(a+b);
System.out.println(a-b);
System.out.println(a*b);
System.out.println(a/b); //结果是0.5 四舍五入结果为0
System.out.println(a/(double)b); //0.5
}
}
public class Demo01 {
public static void main(String[] args) {
//关系运算符返回的结果 布尔值
int a = 10;
int b = 20;
int c = 22;
System.out.println(a>b);
System.out.println(a==b);
System.out.println(c%a); //取余 模运算
}
}
自增、自减的顺序
public class Demo01 {
public static void main(String[] args) {
//自增、自减 一元运算符
int a =3;
System.out.println(a);//a=3
int b =a++;// b=a, a=a+1
System.out.println(a);//a=4;
System.out.println(b);//b=3
int c =++a;//a=a+1. c=a
System.out.println(a);//a=5
System.out.println(c);//c=5;
}
}
幂运算 很多运算,会使用一些工具类来操作 Math.
短路运算
double pow = Math.pow(2,3);
System.out.println(pow);
//短路运算,当判断结果时,如果前一个条件已经是假,就不执行下一个条件,直接返回Flase
int c=5;
boolean d= (c<4)&&(c++<4);
System.out.println(d); //false
System.out.println(c); // c=5,前面已经错了,后面就不执行
位运算
public class Demo01 {
public static void main(String[] args) {
//2*8 = 16,如何计算最快 位运算效率最高
System.out.println(2<<3);
}
}
字符串连接符
//字符串连接符
System.out.println(a+b); //30
System.out.println(""+a+b); //1020
System.out.println(a+b+"");//30
7. 包机制(本质就是文件夹)
比如开发百度 www.baidu.com
8. javaDoc
javadoc 命令是用来生成自己的API文档的
作业:用IDEA生成JavaDoc文档 面向百度
/**
*@author cici
*@version 1.8
*/
四、java流程控制
1. 用户交互Scanner
通过scanner来获取用户的输入
//基本语法
Scanner s = new Scanner(System.in);
.......
通过Scanner类的next()与nextLine()方法获取输入的字符串,在读取前一般需要使用hasNext()与hasNextline()判断是否还有输入的数据
package scanner;
import java.util.Scanner;
public class Demo01 {
public static void main(String[] args){
//创建一个扫描器对象,用于接收键盘数据
Scanner scanner = new Scanner(System.in);
System.out.println("使用next方式接收");
//判断用户有没有输入字符串
if(scanner.hasNext()){
//使用next方式接收
String str = scanner.next();
System.out.println("输入内容为:" +str);
}
凡是属于IO流的类如果不关闭会一直占用资源,要养成习惯,用完关掉
scanner.close();
}
}
输出结果为hello,不是hello world,因为next()不能得到带有空格的字符串,
改成hasNextLine,可正常出结果,以Enter为结束符,返回的是输入回车之前的所有字符,可以获得空白
package scanner;
import java.util.Scanner;
public class Demo01 {
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);
}
scanner.close();
}
}
Scanner scanner = new Scanner(System.in);
System.out.println("请输入数据:");
String str = scanner.nextLine();
System.out.println("输入内容为:" +str);
```java
package scanner;
import java.util.Scanner;
//输入数据
public class Demo03 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int i=0;
float f= 0.0f;
System.out.println("请输入整数:");
if(scanner.hasNextInt()){
i= scanner.nextInt();
System.out.println("整数数据:"+ i );
}
else{
System.out.println("不是整数!");
}
System.out.println("请输入小数:");
if(scanner.hasNextFloat()){
f= scanner.nextFloat();
System.out.println("小数数据:"+ f);
}
else{
System.out.println("不是整数!");
}
System.out.println("请输入整数:");
}
}
package scanner;
import java.util.Scanner;
//输入多个数字,求其总和与平均数,每输入一个数字用回车确认,通过输入非数字来结束输入并输出执行结果
public class Demo04 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
//和
double sum = 0;
//计算输入了多少个数字
int m = 0;
System.out.println("请输入数据;");
//通过循环判断是否还有输入,并在里面对每一次进行求和统计
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();
}
}
``
2. 顺序结构
从上到下,一次执行
3. 选择结构
3.1 if 单选,双选,多选,嵌套
package scanner;
import java.util.Scanner;
//单选
public class IfDemo01 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入内容:");
String s = scanner.nextLine();
//equals判断字符串是否相等
if (s.equals("hello")){
System.out.println(s);
}
System.out.println("end");
scanner.close();
}
}
3.2 switch多选择结构
需要注意case的穿透现象,需要加break语句
public class switchDemo02 {
public static void main(String[] args) {
char grade = 'C';
//case穿透 switch匹配一个具体的值
switch (grade){
case 'A':
System.out.println("优秀");
break; //可选,不选的话case穿透,还会执行以下的
case 'B':
System.out.println("良好");
break;
case 'C':
System.out.println("及格");
break;
case 'D':
System.out.println("挂科");
break;
default:
System.out.println("未知");
}
}
}
public class switchDemo02 {
public static void main(String[] args) {
String name = "cici";
switch (name){
case "mom":
System.out.println("妈妈");
break;
case "dad":
System.out.println("爸爸");
break;
case "cici":
System.out.println("me");
break;
default:
System.out.println("未知");
}
}
}
编译:java 转化为class字节码文件 ,使机器能看懂
反编译;使人能看懂,工具 (IDEA)
如何查找反编译,寻找项目结构proiect structure (在FIle下),点击查看project compiler output 下的文件保存位置,打开可查看得到.class文件
4. 循环结构
4.1 while循环
while循环只要后面的布尔表达式为true,循环就会一直执行
大部分情况我们需要一个让表达式失效的方式来结束循环
但有少部分情况需要循环一直执行,比如服务器的请求响应监听等
正常业务需要避免死循环
public class XunHuan {
public static void main(String[] args) {
//计算1加到100
int i = 0;
int sum = 0;
while(i<=100){
sum =sum +i;
i++;
}
System.out.println(sum);
}
}
4.2 do while 循环
while循环不满足条件则不执行,先判断后执行
do while可以实现至少执行一次,先执行后判断
public class XunHuan {
public static void main(String[] args) {
//计算1加到100
int i = 0;
int sum = 0;
do {
sum =sum +i;
i++;
}while(i<=100);
System.out.println(sum);
}
}
4.3 for 循环
for循环执行的次数在执行前就是确定的
for循环是最有效,最灵活的循环结构,支持迭代
for循环的快捷键 100.for (回车),出现以下结果
//for循环的快捷键 100.for (回车),出现以下结果
for (int i = 0; i < 100; i++) {
}
例程:计算0-100之间的奇数的和和偶数的和
public class XunHuan {
public static void main(String[] args) {
int oddSum = 0;
int evnSum = 0;
for (int i = 0; i <= 100; i++) {
if (i%2!=0){
oddSum+=i;
}
else{
evnSum+=i;
}
}
System.out.println("奇数的和"+oddSum);
System.out.println("偶数的和"+evnSum);
}
}
输出1-1000之间能被5整除的数,并且每行输出3个
public class XunHuan {
public static void main(String[] args) {
for (int i = 0; i <= 1000; i++) {
if (i%5==0){ //如果是5的倍数输出,加一个tab键不换行
System.out.print(i+"\t");//tab键 \t
}
if (i%(5*3)==0){//换行 每第三个数都能被15整除,所以到了每个能被15整除的数的时候换行
System.out.println();
//或者表示成 System.out.print("\n");
}
}
//println 输出完会换行
//print 输出完不会换行
}
}
打印九九乘法表
public class XunHuan {
public static void main(String[] args) {
/* 1. 打印第一列 1*i
2.把固定的1用循环包起来 用j循环
3.去掉重复选项 i<=j
4.调整样式 print 加tab的\t 换行println
*/
for (int j = 1; j<= 9; j++) {
for (int i = 1; i <=j; i++) {
System.out.print(j+"*"+i+"="+(j*i)+"\t");
}
System.out.println();
}
}
}
增强for循环 用于数组或集合的增强型for循环
在java5中引入了一种主要用于数组的增强型for循环
public class XunHuan {
public static void main(String[] args) {
int[] numbers ={10,20,30,40,50};//定义了一个数组
//遍历数组元素
for(int x:numbers){
System.out.println(x);
}
System.out.println("===================");
//结果一样
for (int i = 0; i < 5; i++) {
System.out.println(numbers[i]);
}
}
}
5. break&continue
break在任何循环语句的主体部分都可以用来控制循环的流程。break用于强行退出循环,不执行循环中剩余的语句
continue语句用于终止某次循环的过程,即跳过循环体中尚未执行的语句,接着进行下一次是否执行循环的判定
public class XunHuan {
public static void main(String[] args) {
int i=0;
while(i<100){
i++;
System.out.println(i);
if (i==30){
break;//结果打印到30停止
}
}
System.out.println("123");//然后打印123
}
}
public class XunHuan {
public static void main(String[] args) {
int i=0;
while(i<100){
i++;
if (i%10==0){
System.out.println();
continue;//当i到10的倍数时不执行下一步,立马回到循环开始的地方i++
}
System.out.print(i );
}
}
}
6. 练习
打印三角形
public class XunHuan {
public static void main(String[] args) {
for (int i = 1; i <= 5; i++) {
for (int j = 5; j>= i; j–) {
System.out.print(" “);
}
for(int j=1;j<=i;j++){
System.out.print(”");
}
for (int j = 1; j < i; j++) {
System.out.print("");
}
System.out.println();
}
}
}
五、java方法
1. 何为方法
System.out.println();
/* System :系统的一个类
out:System类下的一个对象,输出对象
println() :方法
*/
方法是语句的集合,他们在一起执行一个功能
方法包含在类或者对象中
方法在程序中创建,在其他地方被引用
设计方法的原则:一个方法只做一个功能
方法的命名规则:首字母小写,后面的是驼峰
public class demo01 {
//main方法 前面的public static是修饰,void表示main返回值类型
public static void main(String[] args) {
//直接调用add方法不行,但是把add方法设置成static就可以了,使它成为类变量
int sum = add(2,3) ;
System.out.println(sum);
test();
}
//加法 public表示修饰,int表示add方法返回一个int型的值
public static int add(int a,int b){
return a+b;
}
//test方法,
public static void test() {
for (int i = 1; i <= 5; i++) {
for (int j = 5; j>= i; j--) {
System.out.print("*");
}
System.out.println();
}
}
}
2. 方法的定义和调用
方法类似于其他语言的函数,是一段用来完成特定功能的代码片段
方法包含一个方法头和一个方法体,下面是一个方法的所有部分;
修饰符:可选,告诉编译器如何调用该方法,定义了该方法的访问类型
返回值类型:方法可能会返回值,写上返回值的数据类型 有些方法执行所需的操作但是没有返回值,在这种情况下,返回值的类型是void
方法名:方法的实际名称,方法名和参数表共同构成方法签名
参数类型:像是一个占位符,当方法被调用时,传值值给参数,这个值被称为实参或变量,参数列表是指方法的参数类型,顺序和参数的个数,参数是可选的,方法也可以不包含任何参数
形式参数:在方法被调用时用于接收外界输入的数据
实参:调用方法时实际传递给方法的数据
方法体:方法体包含具体的语句,定义该方法的功能
修饰符 返回值类型 方法名(参数类型 参数名){
.....
方法体
return 返回值; //return除了返回值,还可以终止方法,比如return 0;
}
什么是值传递,什么是引用传递
3. 方法重载
4. 命令行传参
有时候你希望运行一个程序时再给他传递消息,这就要靠传递命令行参数给main函数来实现
public class demo02 {
public static void main(String[] args) {
for (int i=0;i< args.length;i++) {
System.out.println("args["+i +"]:"+args[i]);
}
}
}
5. 可变参数
在方法声明中,在指定的参数类型后加一个省略号…
一个方法中只能指定一个可变参数,它必须是方法的最后一个参数,任何普通的参数必须在他之前声明
public class demo02 {
public static void main(String[] args) {
demo02 demo = new demo02();//调用test,new一个类,返回当前对象
demo.test(1.5,2,2,3,4,5);
}
public void test(double x,int ... i){
System.out.println(i);
}
}
例程 排序
public class demo02 {
public static void main(String[] args) {
printMax(34,3,2,45,56,768,0.5); //输出768.0
printMax(new double[]{1,2,3}); //输出3.0
}
public static void printMax(double ... numbers){
if(numbers.length == 0){
System.out.println("No argument passed");
return;
}
double result = numbers[0];
//排序
for (int i=1;i<numbers.length;i++){
if(numbers[i]>result){
result= numbers[i];
}
}
System.out.println("max is "+ result);
}
}
6. 递归
public class Demo03 {
public static void main(String[] args) {
System.out.println(f(5));
}
public static int f(int n){
if (n==1){
return 1;
}
else{
return n*f(n-1);
}
}
}
1.边界条件:边界 f(1)
2.前阶段
3.返回阶段n*(n-1)
六、 java数组
1. 数组概述
相同类型数据的有序集合,下标从零开始
2. 数组声明创建
int[] numbers;//首选定义表示方法
int numbers[];
//使用new 操作操作符来创建数组
public class Demo1 {
public static void main(String[] args) {
int[] nums; //1.定义 声明一个数组
nums = new int[3]; //2.开辟空间 创建一个数组
//获取数组的长度 arrays.length
nums[0]=1; //3.给数组元素赋值
nums[1]=3;
nums[2]=7;
System.out.println(nums[2]);
//计算所有元素的和
int sum =0;
//获取数组的长度 arrays.length
for (int i = 0; i < nums.length; i++) {
sum = sum +nums[i];
}
System.out.println("总和为:"+ sum);
}
}
数组的默认初始化:
数组是引用类型,他的元素相当于类的实例变量,因此数组一经分配空间,其中的每个元素也被按照实例变量同样的方式被隐式初始化。
public class Demo1 {
public static void main(String[] args) {
//静态初始化 :创建+赋值
int[] a= {1,2,3,4};
System.out.println(a[0]);
//动态初始化
int[] b = new int[10];
b[0]=10;
System.out.println(b[1]);//没有赋值,默认0
}
}
3. 数组使用
3.1 For-Each循环
public class Demo1 {
public static void main(String[] args) {
int[] arrays = {1,2,3,4};
//输入arrays.for,出现以下
for (int array : arrays) {
// 前面的表示数组里的每个元素,后面的表示数组 没有下标,适合打印输出
System.out.println(array);
}
}
}
3.2 数组作方法入参
3.3 数组作返回值
public class Demo1 {
public static void main(String[] args) {
int[] arrays = {1, 2, 3, 4, 5};
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;
}
}
4. 多维数组
5. Arrays类 数组的工具类
import java.util.Arrays;
public class arrayDemo01 {
public static void main(String[] args) {
int[] a= {1,2,3,463,66,332,20};
System.out.println(a);
//打印数组元素 Arrays.toString
System.out.println(Arrays.toString(a));
printArray(a);
//对数组进行排序
Arrays.sort(a);
System.out.println(Arrays.toString(a));
//填充数组
Arrays.fill(a,2,4,3);//第二个元素到第四个元素填充为3
System.out.println(Arrays.toString(a));
Arrays.fill(a,2);//将元素中的数组全部填充为2
System.out.println(Arrays.toString(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] + ", ");
}
}
}
}
/*
输出结果:
[I@7c30a502
[1, 2, 3, 463, 66, 332, 20]
[1, 2, 3, 463, 66, 332, 20]
[1, 2, 3, 20, 66, 332, 463]
[1, 2, 3, 3, 66, 332, 463]
[2, 2, 2, 2, 2, 2, 2]
*/
一共有八种排序算法:
最出名的是
冒泡排序:时间复杂度是O(n2)
两层循环,外层冒泡轮数,内层依次比较
package Arrays;
import java.util.Arrays;
public class arrayDemo01 {
public static void main(String[] args) {
int [] a={1,2,4,23,12,2345,231,1212,23,12,212};
int[] sort = sort(a);
System.out.println(Arrays.toString(a));
}
//冒泡排序
/*
1.比较数组中,两个相邻的元素,如果第一个数比第二个数大,交换他们的位置
2.每一次比较都会产生一个最大一个最小
3.下一轮少一次排序
4.依次循环,直到结束
*/
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;
}
}
如果要从小到大排,在内层改一下大于小于号
程序的优化:
public static int[] sort(int[] array){
boolean flag = false;//通过flag标识位减少没有意义的比较
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;
flag = true;
}
}
if (flag == false){
break;
}
}
return array;
}
6. 稀疏数组
当一个数组中大部分元素为0,或者为同一值的数组时,可以使用稀疏数组来保存该数组。
稀疏数组的处理方式是:
1.记录数组一个有几行几列,有多少个不同值
2.把具有不同值的元素和行列及值记录在一个小规模的数组中,从而缩小程序的规模
七、面向对象
java的核心思想就是oop 面向对象
1. 初识面向对象
分类的思维模式
对于描述复杂的事物,为了从宏观上把握,从整体上合理分析,我们需要使用面向对象的思路来分析整个系统,但是,,具体到微观的操作,仍然要从面向过程的思路去处理
面向对象编程的本质就是:以类的方式组织代码,以对象的组织(封装)数据
抽象:抽取对象的共同点,再分类
认识论:先有对象,再有类
代码运行:先有类,再有对象
三大特性:封装,继承,多态
2. 方法回顾和加深
package OOP;
import java.io.IOError;
import java.io.IOException;
//demo01就是一个类
public class demo01 {
//main 方法
public static void main(String[] args) {
}
/* 修饰符 返回值类型 方法名字(...参数){
//方法体
return 返回值;//出现return代表方法已经结束了,不能再写别的了
}
*/
public String sayHi(){
return "hi,cici";
}
public void hello(){
return;
}
public int max(int a,int b){
return a>b?a:b;
}
public void readFile(String file)throws IOException{
//抛出异常,例如之前的Arrayindexoutofbounds
}
}
方法的分类:静态方法 static 和非静态方法
//当两个方法都是static类型时,可以相互调用
//一个static不可以调用另一个非static
//非static可以调用static
//两个都是非static也可以互相调用
//和类一起加载的
public void a (){
b();
}
//类实例化之后才存在
public void b(){
}
java是传递而非引用
引用和值传递;
package OOP;
//引用传递:一般传递的是一个对象,本质还是值传递
public class demo01 {
public static void main(String[] args) {
Person person = new Person();
System.out.println(person.name); //null
demo01.change(person);
System.out.println(person.name);//cici
}
public static void change(Person person){
//person是一个对象:指向的:Person person = new Person();这是一个具体的人,可以改变属性
person.name ="cici";
}
}
//定义了一个Person类,有一个属性:name
class Person{
String name;//默认值null
}
3. 对象的创建分析
3.1 创建与初始化对象 以类的方式组织代码,以对象的组织(封装)数据
使用new关键字创建对象
在使用new关键字创建对象的时候,除了分配内存空间之外,还会给创建好的对象进行默认的初始化
以及对类中构造器的使用
// String 对象 = new 类()
一个类,即使里面什么都不写,也会存在一个方法,就是所谓的构造器
比如,构造一个空的类Person,然后在main中调用,也可以运行,打开class文件观察,发现Person类里面已经写上了名字和类一样的Person空方法
这个构造器是默认生成的,也可以自己在方法里面写下来该构造器
无参构造器可以干什么
可以初始化一些信息
如果name没有赋值,那他默认就是null,但是构造器可以实例化一些初始值
构造器的作用:
1.使用new关键字,本质是在调用构造器
2. 用来初始化值
上面为无参构造,以下为有参构造
一旦定义了有参构造,无参构造就必须显示定义,否则无效
比如,删除原来的无参构造,再运行main函数,new Person() 括号内不写值作无参构造,就无效无法运行,会报错,找不到参数
快捷键:alt + insert 调用constructor,生成构造器,可选择有参或者无参,默认生成有参
可以选择勾选一个还是两个参数,重载不同的构造器,在main中就会根据你的输入自动对应不同的方法去
小结:
1.类与对象
类是一个模板,抽象的
对象是一个具体的实例
2.方法
定义 调用
3.对象的引用
引用类型: 除了八大基本类型,其他都算是引用类型
对象是通过引用来操作的 ,栈—>堆,在栈中引用,指向堆中的地址
4.属性 :字段Field 或者称作成员变量
默认初始化:
数字 : 0,0.00
char : u0000
boolean: flase
其他:null
赋值万能公式 属性类型 属性名= 属性值
5.对象的创建和使用:
必须使用new来创造对象,构造器
对象的属性 .name
对象的方法 .fangfa()
6.类:
静态的属性 属性
动态的行为 方法
4. 面向对象三大特性:封装、继承、多态
4.1 封装 高内聚,低耦合
高内聚:类的内部数据操作细节自己完成,不允许外部干涉
低耦合:仅暴露少量的方法给外部使用
***属性私有 : get /set***
通常,应该禁止直接访问一个对象中数据的实际表示,而应该通过操作接口来访问,成为信息的隐藏
//Student 类
package OOP.demo03;
public class Student {
//名字、学号、性别
// private 属性私有
private String name;
private int id;
private char sex;
private int age;
//提供一些可以操作这个属性的方法
// 提供一些public 的get \set 方法
//get 获得数据
// set 设置值
public String getName(){
return this.name;
}
public void setName(String name){
this .name = name;
}
//快捷键 alt+insert 自动生成get和set
public int getAge() {
return age;
}
public void setAge(int age) {
if(age >120||age<0) {
this.age = 3;
}
else{
this.age =age;
}
}
}
//main 中调用
package OOP;
import OOP.demo03.Pet;
import OOP.demo03.Student;
public class Application {
public static void main(String[] args) {
Student s1 = new Student();
s1.setName("cici");
System.out.println(s1.getName());
s1.setAge(999);// 不合法的年龄,在内部加上判定之后封装
System.out.println(s1.getAge());
}
}
结果:
封装的意义:
1.提高程序的安全性,保护数据
2.隐藏代码的实现细节
3.统一接口
4.系统可维护性增加
4.2 继承
继承的本质是对某一批类的抽象。是类与类之间的关系
extends 子类是父类的扩展 关系为 子 “is a” 父
java中只有单继承,没有多继承,一个子类只能有一个父类,父类可以有多个子类,
Object 最顶层的父类
super
NOTE
super注意点
1.调用父类的构造方法,必须在构造方法的第一个
2.super 必须只能出现在子类的方法或者构造方法中
3.super和this不能同时构造方法
VS this
代表的对象
this :本身调用者这个对象
super:代表父类对象的应用
前提
this : 没有继承也可以使用
super:只能在继承条件下才可以使用
构造方法
this():本类的构造
super():父类的构造
方法的重写
只在非静态中出现
只能是public,不能是private
当去掉A和B里面的static的时候,两边出现了圈,向上和向下,代表重载
快键键alt+insert,出现override 代表重写
选择B中test,重写到A中
删除A中的调用super,自己写,结果发生变化
得出结论
静态方法和非静态方法的区别很大
静态方法,只与左边有关,
非静态:子类重写了父类的方法
NOTE:
重写:需要有继承关系,子类重写父类的方法,与属性无关
1.方法名必须相同
2.参数列表必须相同
3.修饰符范围可以扩大不可以缩小,public>Protected>Default>private
4.抛出的异常:范围可缩小不能扩大 ClassNotFoundException -->Exception(大)
子类的方法和父类的方法必须一致,方法体不同
为什么需要重写呢?
父类的功能,子类不一定需要,或者不一定满足
4.3 多态
动态编译: 类型:可扩展性
同一个方法可以根据发送对象的不同而采用多种不同的行为方式
一个对象的实际类型是确定的,但可以指向对象的引用的类型有很多
((Student) s2).eat();//做了强制的类型转换,高转低,就可以调用子类型中的eat
多态注意事项
1.多态是方法的多态,属性没有多态
2.父类和子类,有联系,类型相同,不然会出现类型转换异常ClassCastException
3.存在条件:继承关系,方法需要重写,父类的引用指向子类对象 father f1 = new son();
不能被重写的方法
1.static 静态方法,属于类,不属于实例
2.final 常量
3.private 私有方法
引用类型转换 instanceof 判断一个对象是什么类型
System.out.println(X instanceof Y );
能不能编译通过,取决于XY之间是否存在父子关系
必须有联系,同级无法比较
类型之间的转化:父子
1.父类引用指向子类的对象
2.把子类转换为父类,向上转型
3.把父类转换为子类,向下转型 需要强制转换 可能丢失自己的本来的一些方法
4.方便方法的调用,减少重复的代码
5. 抽象类和接口
5.1 抽象类
//abstract:抽象类 类extends :单继承 (接口可以多继承)
public abstract class Aaction {
//作为一种约束,希望有别人帮我们实现,只写方法名字,没有方法的实现 abstract 抽象方法
public abstract void doSomething();
}
抽象类的所有方法,继承了他的子类,都必须要实现他的方法,除非这个子类也是抽象类
public abstract class A extends Action{
}
//或者
public class A extends Action{
@Override
public void doSomething(){
}
}
抽象类的特点:
1.不能new这个抽象类,只能靠子类去实现他,是一种约束
2.抽象类中可以写普通的方法
3.抽象方法必须在抽象类中
5.2 接口
普通类:只有具体实现
抽象类:具体实现和规范(抽象方法)都有
接口:只有规范!自己无法写方法 专业的约束, 约束和实现分离,面向接口编程
声明类的关键字是class,声明接口的关键字是interface
//创建一个接口
//实现了接口的类,就必须要重写接口中的方法
public interface UserService{
//接口中的所有定义都是抽象的
void add(String name);
void delete(String name);
}
//用一个类来实现该接口
//接口可以多继承
public class UserServiceImp implements UserService,TimeService{
@override
public void add(String name){
}
@override
public void delete(String name){
}
//TimeService是另一个接口 ,接口的多继承
@override
public void timer();
}
接口的作用:
- 约束
- 定义一些方法,让不同的人实现
- 默认方法是public abstract
- 常量 public static final
- 接口不能被实例化,接口中没有构造方法
- implements可以实现多个接口
- 必须要重写接口中的方法
6. 内部类及oop实战
内部类:在一个类的内部定义一个类,定义之后就有了内部类和外部类
-
成员内部类
-
静态内部类
-
局部内部类
-
匿名内部类
八 、异常 Exception
1.检查性异常
2.运行时异常
3.错误
异常处理框架
抛出异常和捕获异常
异常处理的五个关键字:
try catch finally throw throws
//快捷键;ctrl +alt +T
//catch (想要捕获的异常类型) 最高级为throwable
假设要捕获多个异常,从小到大的捕获
//finally 可以不要,假设IO、资源、关闭,放在finally里,做善后工作
太复杂了,没有看懂,后续有这种问题再具体分析叭