目录
1.Java面向对象方法
1.1. 创建类和对象的方法
1.2. this的使用
1.3. 静态域和静态方法
1.3.1. 静态域:属于类的级别
1.3.2.静态常量
1.3.3 静态方法
1.3.4. 工厂方法
1.3.5. main方法
1.4. 对象构造
1.4.1. 对象重载
1.4.2. 类的构造器以及初始化
1.5. 包
2. Java的继承
2.1. 继承的语法
2.2. 继承中的对象转型
2.2.1. 对象向上转型
2.2.2. 对象向下转型
2.3. 阻止继承:final类和方法
2.4.抽象类和抽象函数
2.4.1. 定义方法与语法特征
2.4.2. 为什么用抽象类?
3. 包的访问权限
3.1. 将类放到包中
3.2. 包的访问权限有哪些
4. 接口
4.1. 什么是接口
4.2.接口语法
4.3. 接口的应用
5. Java的异常处理
5.1. JDK异常的分类和try-catch捕捉
5.2. 用户自定义的异常处理
6. Java中的IO
6.1. IO的定义和分类,以及字节流基本用法:
6.2. 大文件的读写方法和字符流的使用
1. 大文件读写
2.字符流
6.3. 节点流和处理流
1. 处理流: BufferedReader:字符输入处理流
7.内部类和匿名内部类
7.1. 内部类
7.2. 匿名内部类
1.Java面向对象方法
继承
封装
多态
this的用法
引用隐式参数
调用该类其他的构造器
super的用法
调用超类方法
调用超类的构造器
1.1. 创建类和对象的方法
对象和引用的一个关系图:
模板:
classClassName{ field1// 属性: 描述类的状态field2 ... constructor1 constructor2 ... method1// 方法: 描述类的行为method2}
下面是一个简单的实例
publicclassMain{publicstaticvoidmain(String[] args)throwsIOException{// 对象的使用方法 // 对象.变量: staff.name// 对象.函数(): staff.getname()Employee[] staff =newEmployee[3]; staff[0] =newEmployee("Zhang",75000,1977,12,15); staff[1] =newEmployee("Li",23000,1932,3,5); staff[2] =newEmployee("Zhang",56444,1964,6,21);for(Employee e: staff){ e.raiseSalary(5); }for(Employee e: staff){ System.out.println("name="+ e.getName() +", salary="+ e.getSalary() +", hireday="+ e.getHireDay()); } }}// 一个类可以有无限多个对象classEmployee{// 三个实例域用来存放将要操作的数据privateString name;privatedoublesalary;privateLocalDate hireDay;// 构造器(与类名同名),总是伴随着new操作符的执行而被调用 // 每个类可以有一个以上的构造器// 如果类中没有构造器,java会默认有一个构造器用于初始化// 但是如果类的构造器大于1个的话,需要自己构造默认构造器// 构造器可以有0,1,...等多个参数// 构造器没有返回值,即没有void// 构造器总是伴随着new的操作一起调用publicEmployee(String n,doubles,intyear,intmonth,intday){ name = n; salary = s; hireDay = LocalDate.of(year, month, day); }// 需要获得或者设置实例域的值,需要提供以下三个内容: // (1).一个私有的数据域// (2).一个公有的域访问器方法// (3).一个公有的域更改器方法publicStringgetName(){returnname; }publicdoublegetSalary(){returnsalary; }publicLocalDategetHireDay(){returnhireDay; }publicvoidsetHireDay(LocalDate hireDay){this.hireDay = hireDay; }publicvoidsetName(String name){this.name = name; }publicvoidsetSalary(doublesalary){this.salary = salary; }// class方法有两个参数: 显示参数(括号内部的参数) + 隐式参数(引用该方法的对象)// 用this来表示隐式参数,表示使用该方法的对象publicvoidraiseSalary(doublerate){// 可以直接访问类的属性doubleraise =this.salary * rate /100;this.salary =this.salary + raise; }}
1.2. this的使用
使用this调用成员变量和成员函数
使用this调用构造函数
classPerson{ String name;intage; String address; Person(){ System.out.println("无参数"); } Person(String s,inta){this.nanme = s;this.age = a; }// this可以调用构造函数Person(String s,inta, String s2){this(s, a);this.address = s2; }// this为使用该方法的对象,也称为类的隐式参数voidtalk(){ System.out.println("my name is "+this.name) }}
1.3. 静态域和静态方法
1.3.1. 静态域:属于类的级别
一般变量: 对象.变量
静态变量: 类名.变量 + 对象.变量
如果将一个域定义为static, 每个类中只有一个这样的域, 而每个对象对于所有的实例域却有自己的一份拷贝, 比如我们创建一个class:
classEmployee{privatestaticintnextID =1;privateintid;}
如果有1000getEmployee类的对象,就有100个实例域id,但是只有一个静态域nextId
1.3.2.静态常量
// 1000个对象有1000个拷贝publicfinaldoublePI =3.14;// 1000个对象只有一个PIpublicstaticfinaldoube PI =3.14;
1.3.3 静态方法
静态方法是一种不能向对象实施操作的方法,只能通过类名调用,也就是说没有this隐式参数
非静态方法: employee.getNextID()
静态方法: Employee.getNextID()
静态函数中不能使用非静态变量(非静态域)
1.3.4. 工厂方法
1.3.5. main方法
publicclassMain{// main是一个静态方法,不对任何对象进行操作 // 事实上,再启动程序的时候没有任何对象,静态main方法将执行并创建程序需要的对象publicstaticvoidmain(String[] args){ System.out.println("Hello World!"); }}
1.4. 对象构造
1.4.1. 对象重载
如果多个方法有相同的名字、不同的参数,便产生了重载,编译器根据传入的参数自动旋转哪个方法
StringBuilder msg =newStringBuilder();StringBuilder msg =newStringBuilder("To do: \n");
1.4.2. 类的构造器以及初始化
classEmployee{privatestaticintnextId;privateintid;privateString name;privatedoublesalary;//初始化块中初始化值{ id = nextId; nextId++; }// 构造器中初始化值publicEmployee(){ name =""salary=0; }publicEmployee(String n,doubles){this.name = name;this.salary = s; } }
1.5. 包
管理class文件的
导入类文件: import java.util.*
将类文件放到包中: package com.horstman.corejava
2. Java的继承
一个类得到了另外一个类的成员变量和成员函数
Java只支持单继承,不允许多继承
2.1. 继承的语法
publicclassMain{publicstaticvoidmain(String[] args){// 生成子类的过程student st =newstudent("zhang",20,6); st.introduce(); }}// 将重复代码放到父类中去classPerson{ String name;intage;publicPerson(){ System.out.println("Person无参数"); }publicPerson(String name,intage){this.name = name;this.age = age; }voideat(){ System.out.println("吃饭"); }voidintroduce(){ System.out.println("my name is "+this.name +", my age is "+this.age); }}classstudentextendsPerson{intgrade;// 自动继承父类的成员变量和成员函数// 在子类的构造函数中,必须调用父类的构造函数publicstudent(String name,intage,intgrade){super(name, age);this.grade = grade; }// 子类可以写自己的成员函数voidstudy(){ System.out.println("Study"); }// 复写 父类的方法// 1. 在具有父子关系的两个类当中// 2. 父类和子类中各有一个函数,这两个函数的定义(返回值类型,函数名和参数列表)完全相同@Overridevoidintroduce(){super.introduce(); System.out.println("my grade is "+this.grade); }}
2.2. 继承中的对象转型
2.2.1. 对象向上转型
将子类的对象赋值给父类的引用
// s是学生,也是人//s: 变量(name,age,address) + 函数(introduce, study)Student s =newStudent();//p:变量(name,age) + 函数(introduce)Person p = s;// 一个引用能够调用哪些成员变量和函数,取决于这个引用的类型(p引用person,看p前面的类型)// 一个引用调用的哪个方法,取决于这个引用所指向的对象(p指向的是student对象,调用student方法)p.name ="zhang";p.age =12;// p.address = "bj" 不可以使用(他说)p.introduce();// 调用的是子类的Introduce()// p.study() 不可以使用
2.2.2. 对象向下转型
Student s1 =newStudent();Person p = s1;Student s2 = (Student)p;
2.3. 阻止继承:final类和方法
将类定义为final后,无法继承
将类的方法定义为final后,子类无法覆盖该方法
publicclassfinalMotherextendsPerson{ ....;}publicclassstudentextendsPerson{publicfinalString getName{ ....; }}
2.4.抽象类和抽象函数
面向对象思想:先抽象,后具体
2.4.1. 定义方法与语法特征
只有函数的定义,没有函数体的函数
抽象类不能生成对象(如果能的话,可能调用抽象函数,但是抽象函数没有函数体,无法解释)
抽象类天生是当爹的,只能被继承,它的子类可以生成对象
如果一个类中包含抽象函数,那么类必须被声明为抽象类
如果一个类中没有抽象函数,也可以声明为抽象类
抽象类可以有构造函数
publicclassMain{publicstaticvoidmain(String[] args){ Person p =newChinese(); p.eat(); }}// 抽象类abstractclassPerson{ String name;intage;publicPerson(){ System.out.println("Person无参数"); }publicPerson(String name,intage){this.name = name;this.age = age; }// 抽象函数abstractvoideat();voidintroduce(){ System.out.println("my name is "+this.name +", my age is "+this.age); }}classChineseextendsPerson{ Chinese(){super(); System.out.println("chinese的构造函数"); }@Overridevoideat(){ System.out.println("用筷子吃饭"); }}
2.4.2. 为什么用抽象类?
抽象类表达的是一种抽象的概念,属于比父类还抽象的类
抽象函数可以检查子类是否复写了抽象函数,是一种检测机制,检测是否子类有没有写应该复写的抽象函数
publicclassMain{publicstaticvoidmain(String[] args){ Person[] p =newPerson[2]; p[0] =newEmployee("zhang",5000,2018,10,12); p[1] =newStudent("Li","CS");// i.getDescription()中由于不能构造抽象类Person的对象,所以变量i永远不会引用person对象,而是引用employee或者student子类的具体对象 for(Person i:p){ System.out.println(i.getName() +","+ i.getDescription()); } }}// 将重复代码放到父类中去abstractclassPerson{abstractStringgetDescription(); String name; Person(String name){this.name=name; }publicStringgetName(){returnname; }}classEmployeeextendsPerson{doublesalary; LocalDate hireday; Employee(String name,doublesalary,intyear,intmonth,intday){super(name);this.salary = salary; hireday = LocalDate.of(year,month, day); }publicdoublegetSalary(){returnsalary; }@OverridepublicStringgetName(){returnsuper.getName(); }publicLocalDategetHireday(){returnhireday; }@OverrideStringgetDescription(){returnString.format("an employee with a salary of %.2f", salary); } }classStudentextendsPerson{ String major; Student(String name, String major){super(name);this.major = major; }@OverridepublicStringgetName(){returnsuper.getName(); }publicStringgetMajor(){returnmajor; }@OverrideStringgetDescription(){return"a student majoring in"+ major; }}
zhang,an employeewitha salaryof5000.00Li,a student majoring inCS
3. 包的访问权限
3.1. 将类放到包中
什么是软件包?
怎么讲类放到软件包中?
将类放到一个包中,需要使用packcage “包名”
编译时需要使用 -d参数,该参数的作用是依照包名生成相应的文件夹
一个类的全名: 包名 + . + 类名:mars.Test
包名的命名规范
一般小写
一般是域名倒过来写: io.github.com.haochen95;
packagemars;classTest{publicstaticvoidmain(String[] args){ System.out.println("package") }}
3.2. 包的访问权限有哪些
访问权限含义包内可否使用包之间可否使用包内继承包间继承
public公有权限YesYesYesYes
private(很少修饰类)私有权限NoNoNoNo
default包级别访问权限YesNoYesNo
protected(不修饰类)受保护权限YesNoYesYes(只有子类才能使用)
如果子类和父类不在同一个包中,子类确实继承到了父类的成员变量和成员函数,然后再检查权限,看是否能够使用
public > protected > default > private
4. 接口
4.1. 什么是接口
4.2.接口语法
使用Interface定义
接口中的方法全是抽象方法
接口中的方法全是public权限
实现接口使用implements关键字
一个类可以实现多个接口
一个接口可以继承多个接口
// 定义接口interfaceUSB{publicvoidread();publicvoidwrite();}interfaceWIFI{publicvoidopen();publicvoidclose();}// 继承接口classPhoneimplementsUSB,WIFI{publicvoidread(){ System.out.println("USB READ") }publicvoidwrite(){ System.out.println("USB WRUTE") }publicvoidopen(){ System.out.println("WIFI OPEN") }publicvoidclose(){ System.out.println("WIFI CLOSE") }}// 主函数中调用 classTest{publicstaticvoidmain(String[] args){ Phone phone =newPhone(); USB usb = phone; usb.read(); usb.write(); WIFI wifi = phone; wifi.open(); wifi.close(); }}
4.3. 接口的应用
在继承中,可以将重复代码放到父类中
但是所有子类都需要使用类似的方法体,可能使用接口更加的合适
接口定义了一种标准,接口只定义应该有这些方法,但是不关心方法的具体实现方法,由每个子类自己去实现
5. Java的异常处理
5.1. JDK异常的分类和try-catch捕捉
异常:终端了正常指令流的事件;
程序在异常处会中断,退出程序
使用try-catch捕捉异常(对于track error必须使用)
try{ System.out.println(4);// 没出异常,继续执行/出了异常跳到catch执行,再继续执行}catch(Exception e){ e.printStackTrace(); System.out.println(5);}finally{// 异常出不出 都会执行这个程序-----主要用于IO流的关闭文件代码System.out.println(6);}System.out.println(7);
5.2. 用户自定义的异常处理
throw和throws关键字的用法
publicvoidsetAge(intage){if(age<0){// untrack excaption---程序运行到这里就会终止RuntimeException e =newRuntimeException("年龄不能为负数");throwe;// track excaption --- 必须用try-catch进行捕捉或者声明(throws Exception)放在类声明中Exception e =newException("年龄不能为负数")throwe; }}
6. Java中的IO
6.1. IO的定义和分类,以及字节流基本用法:
IO的目标:从数据源(文件,键盘,网络)中读取数据,从数据写入到数据目的地(文件,屏幕,网络)当中
输入和输出流在Java中都设置成一种"管道", IO流也是一种对象
IO的分类
输入输出流
字节流,字符流
节点流,处理流
IO流中的核心类: InputStream(抽象类) <- FileInputStream, OutputStream(抽象类) <-FileoutputStream
-InputStream: int read(byte[] b, int off, int len),返回读取了多少字节的数据
-OutputStream: void write(byte[] b, int off, int len)
importjava.io.*;// 字节流classTest{publicstaticvoidmain(String[] args){// 声明输入流引用FileInputStream fis =null;// 声明输出流引用FileoutputStream fos =null;try{// 字节流-读数据: 生成代表输入流的对象fis =newFileInputStream("D:/from.txt");// 生成代表输出流的对象fos =newFileoutputStream("D:/to.txt");// 生成一个字节数组byte[] buffer =newbyte[100];// 调用输入流的read方法,读取数据inttemp = fis.read(buffer,0,100);// 写入到文件中fos.write(buffer,0, temp); String s =newString(buffer);// 将字节转为字符// 去除空格s = s.trim(); System.out.println(s); }catch(Exception e){ System.out.println(e); } }}
6.2. 大文件的读写方法和字符流的使用
1. 大文件读写
importjava.io.*;classTest{publicstaticvoidmain(String[] args){ FileInputStream fis =null; FileoutputStream fos =null;try{ fis =newFileInputStream("D:/from.txt"); fos =newFileoutputStream("D:/to.txt");byte[] buffer =newbyte[100];// 大文件:循环读取while(true){inttemp = fis.read(buffer,0,100);// 读到文件最后的时候,read返回-1if(temp == -1){break; } fos.write(buffer,0, temp); } }catch(Exception e){ System.out.println(e); }finally{// 一定要在finally中关闭文件管道try{ fis.close(); fos.close(); }catch(Exception e){ System.out.println(e); } } }}
2.字符流
读写文件是,以字符为基础
核心方法:Reader(抽象类) <- FileReader, Writer(抽象类) <-FilWriter
-Reader: int read(char[] b, int off, int len),返回读取了多少字节的数据
-Writer: void write(char[] b, int off, int len)
importjava.io.*;classTest{publicstaticvoidmain(String[] args){ FileReader fr =null; FilWriter fw =null;try{ fr =newFileReader("D:/from.txt"); fw =newFIleWriter("D:/to.txt");char[] buffer =newchar[100];inttemp = fr.read(buffer,0,buffer.length); }catch(Exception e){ System.out.println(e); }finally{// 一定要在finally中关闭文件管道try{ fr.close(); fw.close(); }catch(Exception e){ System.out.println(e); } } }}
6.3. 节点流和处理流
1. 处理流: BufferedReader:字符输入处理流
readline功能
生成BufferedReader对象的方法:
BufferedReader in = new BufferedReader(new FileReader("D:/from.txt"))
importjava.io.*;classTest{publicstaticvoidmain(String[] args){ FileReader fileReader =null; BufferedReader bufferedReader =null;try{ fileReader =newFileReader("D:/from.txt"); bufferedReader =newBufferedReader(fileReader);// 按照一行一行的读取Strign line =null;while(true){ line = bufferedReader.readline();if(line ==null){break; }// 打印每一行System.out.println(line) } }catch(Exception e){ System.out.println(e); }finally{// 一定要在finally中关闭文件管道try{ fileReader.close(); bufferedReader.close(); }catch(Exception e){ System.out.println(e); } }}}
7.内部类和匿名内部类
7.1. 内部类
生成内部类的对象: A.B b = new A().new B();
classA{inti;// 内部类:A&B.classclassB{intj;intfunB(){// 内部类可以随意使用外部类的变量intresult = i+j;returnresult; } }}classtest{publicstaticvoidmain(String[] args){// 生成内部类的对象A a =newA(); A.B b =newA().new B(); a.i =3; b.j =1; b.funB();// 结果是 3 + 1 = 4;}}
7.2. 匿名内部类
interfaceA{publicvoiddosomething{};}classB{publicvoidfun(A a){ System.out.println("B lei"); a.dosomething(); }}classTest{publicstaticvoidmain(String[] args){ B b =newB();// 利用匿名内部类 来继承父类或者实现接口b.fun(newA(){publicvoddosomething(){ System.out.println("Do domething"); } }) }} 欢迎工作一到五年的Java工程师朋友们加入Java群: 741514154
群内提供免费的Java架构学习资料(里面有高可用、高并发、高性能及分布式、Jvm性能调优、Spring源码,MyBatis,Netty,Redis,Kafka,Mysql,Zookeeper,Tomcat,Docker,Dubbo,Nginx等多个知识点的架构资料)合理利用自己每一分每一秒的时间来学习提升自己,不要再用"没有时间“来掩饰自己思想上的懒惰!趁年轻,使劲拼,给未来的自己一个交代!