Java 学习笔记
JAVA学习笔记
目录
1.JAVA基础知识点简介
1.什么是环境变量:通常是指在操作系统当中,用来指定操作系统运行时所需要的参数。
2.Path环境变量:是操作系统外部命令搜索路径。
3.window+R,输入cmd 输入 ipconfig ,按下命令,显示计算机网卡配置
-
为什么会有这个结果?
-
其实是操作系统执行ipconfig.exe的可执行文件。
4.操作系统在哪里找这个ipconfig.exe 这个文件在电脑路径:C:\Windows\System32 中有ipconfig.exe的文件。如果改变ipconfig 的名字为iconfig ,再次在cmd里面输入ipconfig命令,提示不是内部或外部命令,也不是可运行的程序。
例如:系统环境变量
- %SystemRoot%\system32
- %SystemRoot%\System32\Wbem
- %SYSTEMROOT%\System32\WindowsPowerShell\v1.0\
- C:\Program Files\Java\jdk1.8.0_05\bin\
- 首先执行的时候系统会从第一个路径开始搜索有没有ipconfig.exe 这个名字的文件可执行命令,如果有则执行。
5.在路径 :C:\Program Files\Java\jdk1.8.0_05\bin 中有java.exe 这个文件,如何找到这个文件也是通过系统Path路径。
6.classpath环境变量:类文件搜索路径 "."代表是当前目录 执行 Hello.class这个文件需要去哪里找这个文件? "." 代表在当前目录去寻找。
7.总结:Path 用来寻找命令的路径,classpath用来寻找类文件的路径(以 .class为结尾的文件就是类文件。)
8.JDK 里面有什么东西?
- 重点:JRE 是(Java Runtime Environment)Java运行环境,包括以下部分:
- 例子:吃饭需要一个环境,睡觉需要环境,工作需要环境。做任何一件事情,需要一些基础 知识,比如厨师脱离厨房就做不了食物。
- JDK安装教程:java的JDK安装教程
9.JVM是Java Virtual Machine(Java虚拟机)的缩写,他是由一个软件虚拟出来的计算机,不是实际的计算机。
流程:1.程序员写程序,编译器检测是否通过,不通过返回。
(编译器把程序翻译成虚拟机可以理解的代码)
2.编译成计算机识别的二进制代码(.class files)。
3.在不同平台运行,是虚拟机需要完成的东西。
4.虚拟机把(.class)文件翻译成操作系统可以理解的代码。
1.1.java的JDK安装教程
-
首先在官网下载jdk安装包
-
官网链接:点我下载
- 下载完成,安装jdk默认安装在C盘上:C:\Program Files\Java\jdk1.8.0_144
- 博主选择默认安装位置,如果怕占位置可以自行改变
- 安装jre,同样默认位置:C:\Program Files\Java\jre1.8.0_171
- 验证安装是否成功:
- 打开window的命令(cmd)窗口输入:java - version 查看jdk的版本号。
- 成功显示版本号,表示安装成功。
- 接下来一步很关键,配置环境变量。在前面我们已经解释过系统环境变量的作用了
- 电脑打开:我的电脑右键-->属性--->高级系统设置下找到环境变量。
- 创建系统变量: 变量名,JAVA_HOME 变量值,java的jdk路径(C:\Program Files\Java\jdk1.8.0_144)
- 注意换成你的JDK安装位置
- 再创建一个系统变量,类文件搜索路径:变量名,CLASSPATH,变量值, "."
- 我们前面说过classpath是类文件搜索路径,“.”代表在当前目录搜索
- 在Path路径添加连个路径:%JAVA_HOME%\bin;%JAVA_HOME%\jre\bin
- 提示:%JAVA_HOME% 的意思是JAVAHOME环境变量的内容
- %JAVA_HOME%等价于C:\Program Files\Java\jdk1.8.0_144
- 至此jdk安装完成。
2.JAVA的变量
-
什么是变量?
答:要将信息存储在计算机当中,就必须指明信息存储的位置和所需的内存空间。
11.变量的类型:
- 基本数据类型 :1.整数类型:byte,short,int,long 2.浮点类型:float,double 3.字符型: char 4.(布尔型:boolean,只能为true 和 false)。
- 引用数据类型 :1. 类: class 2.接口:interface 3.数组 4.String
类型 |
占用存储空间 |
表数范围 |
byte |
1字节 |
-128~127 |
short |
2字节 |
-2的15次方~2的15次方-1 |
int |
4字节 |
-2的31次方~2的31次方-1 |
long |
8字节 |
-2的63次方~2的63次方-1 |
浮点类型 |
|
|
float |
4字节 |
|
double |
8字节 |
|
-
十进制整数,如12,-314,0。1).Java语言整型常量的三种表示形式:
-
八进制整数,要求以0开头,如012。
-
十六进制数,要求0x或0X开头,如0x12。
2).Java语言的整型常亮默认为int 型,如 :int i=3;
3).声明long型常亮可以后加'l'或者'L',如 long l=3L;
12.变量命名规范:
1.变量命名语法规范:
1).应该以字母、下划线或者美元符开头。
2).后面跟字母、下划线、美元符或者是数字。
3).Java变量名没有长度的限制。
4).Java变量名对大小写敏感。
2.驼峰命名法:
1).变量名应该是有意义的英文单词。
2).变量名如果只有一个单词,则所有字母小写。
3).变量名如果由多个英文单词组成,则从第二个单词开始首字母大写。
13.Java字符使用Unicode字符集:
ASCII全称为:American Standard Code for Information Interchange(美国标准信息交换码)
1.对字符集的理解可以从以下几方面入手:
1).在计算机当中,所有的数据都需要使用二进制数字表示
2).类似a、b、c之类的字母无法直接用二进制表示。
3).所以就将所有常见的符号进行编号。标准ASCII码使用7位二进制数来表示字符。
4).7位2进制可以表示所有的数字,大写字母以及一些常见的符号。 (例如:!,@,#,$等等)
2.Unicode 为每种语言的每个字符设定了统一并且唯一的二进制编码
1).Unicode满足了跨语言文本转换和处理的需求。
2).Unicode在互联网当中扮演着十分重要的角色。
3).Unicode使用数字0-0x10ffff来表示字符。
4).最多允许1114112个字符。
例子:打开文本编辑器:输入联通,保存,再次打开,出现乱码?
答: 当写入联通两个字的时候,是通过字符集,装换成数字,存放在硬盘如果用 a字符 集,转换联通存入一个二进制到硬盘,读取的时候,用 b字符集翻译回来,就会出错。
14.Java与Unicode字符集
答:由于Java在设计初期就考虑到将语言使用在互联网当中,所以设计者们就选用Unicode 字符集,这也使得Java程序 能够在互联网当中更好的流通,也正是由于这样的原因,以下代 码是合法的:char c = '中';
- 在Unicode当中,一个中文字符和一个英文字符所占的字节数是一样的。
3.什么是面向对象 ,如何学习?
15.什么是面向对象?
1).面向对象是一种编程方法。
2).面向对象是一种思维方式。
3).面向对象不是一种编程语言。
16.如何学习面向对象?
1).掌握一门面向对象语言的语法。
2).掌握面向对象的思维方式(现实方式的思维方式)。
2.1).首先确定谁来做,其次确定怎么做。
2.2).首先考虑整体,其次考虑局部。
2.3).首先考虑抽象,其次考虑具体。
3).熟悉面向对象设计原则(呈金字塔型,消除应用程序重复代码)。
4).掌握面向对象的设计模式(前人设计经验总结,解决问题的方法)。
4.创建类的方法 ,类的表示方法?
17.创建
-
创建类的方法:
class 类名(相当c语言的结构体)
{
属性; //属性也叫成员变量,主要用于描述类的状态
方法; //方法也叫成员方法,主要用于描述类的行为
}
-
类的表示方法:
class Person{ //Person为类名
int age; //age为成员变量
void shout() { //shout 为成员函数
System.out.println("oh,my god! I am" + age);
}
}
-age是类的属性,也叫类的成员变量。
-shout是方法也叫类的成员函数。
-shout方法可以直接访问同一个类中age变量,如果一个方法中
有与成员变量同名的局部变量,该方法中对这个变量名的访问
时局部变量,而不是成员变量。
-
生成对象的方法:
例子:在c语言中定义一个结构体:
typedef struct st{
int age;
int high;
}Dog;
例子:在Java中创建一个名为 Dog 的类。
引用过程:创建一个新(引用)变量:Dog dog;
格式:类名 对象名=new 类名();
例如:Dog dog =new Dog(); //已经定义一个Dog的对象
Dog和int 是一个意思,是一个类型,而Dog是一个引用数据类型(跟c语言的结构体是一样的)。
1.Dog d //创建一个Dog的引用
2.new Dog(); //创建一个Dog对象
3.= //将创建的Dog对象赋值给引用‘d’
5.1.类和对象的关系
类是抽象的,一系列具有共同特征的事物,比如狗,有身高体重,而对象是具体的,比如具体是哪一条狗。
18.使用变量和函数:
1).对象的使用方法:
- 使用对象调用变量和函数:对象.变量
例子:在Dog.java 中创建一个类
在Text.java 中创建一个对象和调用对象
运行Text.java
进去命令运行窗口:
然后再进入你文件所在的位置:
- 注意:在这里提示一下,编译java文件的时候最好不要使用window自带的文本编辑器,容 易出现一些摸不着头脑的错误,博主使用的是Notepad++文本编辑器。
- 下载链接:NodtPad下载链接,密码:38hc
5.2.函数的重载
19.函数的重载:
1.两个或多个函数出现在同一个类当中。
2.函数名相同。
3.参数列表不同。
例子:在A.java 中建立一个类:
在Text.java 中
输出结果:
通俗例子:生活中有 “洗”这个概念,洗衣服也是洗,洗脸也是洗,不能用同样的方法去洗,洗是一个抽象的概念,洗什么是具体的事件。
5.3构造函数 (函数和函数名相同,没有返回值)
构造函数:函数和函数名相同,没有返回值
在Text.java 中
运行结果:
构造函数的例子:
在Text.java 中
运行结果:
注意:如果一个类没有建立构造函数,这个类在运行的时候就会自动为这个类添加一个参数为空何函数体为空的构造函数,如果一个类中已经有构造函数,编译器不会自动添加参数为空的构造函数(调用无参数的构造函数就会出错)。
6.this关键词的用法
使用this调用成员变量和成员函数,使用this调用构造函数
1).例子:创建一个Person.java 的文件
- 再创建一个Text.java的函数入口
- 运行结果:
- 例子:“我” 这个词,当张三说:我的年龄为15岁,这个”我“代表张三。 当李四说:我的年龄为16岁,这个“我”代表李四。
2).this的第二种用法:
- 例子:创建一个Person.java 的文件
- 再创建一个Text.java的函数入口
- 输出结果:
7.static 关键字的用法
static 关键字的用法:
1.静态成员变量只有一份。
2.在静态函数当中不能使用this.
3.静态代码块的主要作用是为静态成员变量赋值。
1). 静态成员变量的语法特点:
如何定义:在变量前面加一个 static int i;
- 普通成员变量:
Person p1 = new Person();
P1.i=10;
Person p2 = new Person();
P2.i=20;
- 如果“i”为静态变量,他们使用同一个变量:
- 在Person.java 文件中定义一个类:
注意:所有的静态变量使用的是同一个,无论是p1修改还是p2修改这个i成员变量的值,这个值就会同时变化;
- 在Text.java 文件中写主函数
- 输出结果为:
2). 静态函数的语法特点:
- 例子1:
- 编译通过没有错误。
- 例子2:
- 编译出错:
- 解释:在静态函数中,不能直接引用非静态变量。
- 3). 静态代码块的语法特点:
- 例子3:
- 在Text.java 中代码如下:
- 运行java Text结果为:
- 分析:静态代码开无需调用,在装载的时候自动调用。
8.继承(三大特征:继承,封装,多态)
继承(三大特征:继承,封装,多态),为了减少应用程序的重复代码
什么是继承?
-
在现实生活中,继承就是儿子得到了老子的东西。
-
在面向对象的世界当中,继承就是一个类得到了另一类当中的成员变量和成员函数的方法。
注意:Java只支持单继承,不允许多继承。
例子1:
如何继承一个类?
- 新建一个类 Student.java 文件(让Student 类去继承Person 这个类)
//Person 为父类,Student 为子类,extends为继承的关系
- 如果为继承关系,那Student这个类应该也有name ,eat(),introduce(),成员变量和方法。
证实:
- 新建一个Text.java 的类
执行步骤:1.编译javac Person 2.编译 javac Student 3.编译 javac Text 4.执行java Text
--除了继承还可以增加新的东西?
然后修改 Text.java
输出结果:
8.1.使用super调用父类构造函数的方法
-
生成子类的过程
注意:子类能继承父类的成员变量和函数,却不能继承父类的构造函数,在成员变量赋值的时候可能出现重复代码,可以通过调 用 super();来调用父类的构造函数
例子1:1).建立Person.java的文件,加上构造函数
2).定义一个Student 的类,继承Person,但是构造函数不能被继承;
3).建立一个Text.java 的函数入口
输出结果:
如果在子类Student.java当中代码是这样
在Text.java 文件中,创建一个新的对象 student
运行结果:
8.2函数的复写
函数的复写(voerride)/使用super 调用父类的成员函数
1.函数的复写
例子 :
2).再创建一个子类 Student ,继承父类 Person 的name ,age ,introduce();
3).创建一个类,调用Student 函数
运行结果:
9.JAVA的对象转型(面向对象多态性的一种体现)
9.1向上转型
1).什么是对象的向上转型?
向上转型—将子类的对象赋值给父类引用。(一定可以成功)
前提:Student 是 Person 的子类。
例如:s 代表张三这个学生对象。说张三是个Person对象也是没毛病。
例子:
2).再创建一个子类 Student,继承父类Person
3).创建一个类,调用Student 函数
注意:1.一个引用能调用那些成员(变量和函数),取决于这个引用类型。
2.一个引用调用的是哪一个方法,取决于这个引用所指的对象。
输出结果:
9.2向下转型
2).什么是向下转型?
- 向下转型:将父类的对象赋值给子类引用。
//首先向上转型
Student s1 = new Student();
Person p = s1;
Student s2 = (Student)p; //强制类型转换
- 例子:
class Text{
public static void main(String args[]){
Student s1 = new Student(); //生成一个新的 Student 的对象p
Person p = s1; //首先向上继承
Student s2 = (Student)p; //再向下继承
}
}
10.模拟客户需求例子(面向对象方法)
模拟需需求场景,应用前面所学知识。
1).客户的第一要求:开发一个打印机控制程序,能够实现开机、关机、和打印功能。
- 程序员:先建一个类 Printer.java
- 建立一个类 Text 用于测试:
- 测试:
2).客户二次需求:我的办公室加了一台新的打印机,把你的程序修改一下,应该很 简单吧(不是同一个型号)。
1.修改打印机的类名为 HPPrinter.然后再增加一个类 CanonPriner
2.测试程序:
--虽然程序开发完成了,但是存在很多重复代码??????????
如果类越多,重复代码就越多。
解决方案: 惠普打印机和佳能打印机都是打印机,则创建一个类为打印机这个类,则打印机为父类,佳能和惠普继承这个父 类。
- 创建父类,Printer
2.创建惠普 HPPrinter 这个类 继承父类 Print
3.创建佳能 CannonPriner 这个类,继承父类Print
重复代码全部消除,如果再次添加一个打印机就会容易很多,我们只需要新建一个类去继承Printer这个类,然后根据功能复写父类
11.抽象类和抽象函数
抽象类和抽象函数
1.抽象函数就是没有函数体的函数。
2.抽象函数使用abstract 来定义
3.抽象类不能生成对象,但是却可以拥有构造函数。
1).抽象函数的语法特征
函数的定义:有返回值类型,函数名,参数列表
函数体 :大括号,和大括号中间的内容
什么是抽象函数?
答:只有函数的定义,没有函数体的函数,被称为抽象函数。
abstract void fun();
2).抽象类的语法特征
什么是抽象类?
使用abstract 定义的类被称为抽象类。
-
抽象类不能生成对象。
-
如果一个类中包含有抽象函数,那么这个类必须被声明为抽象类。
-
如果一个类当中没有抽象函数,那么这个类也可以被声明为抽象类。(不能被生成对象,被称为基类,只能被继承)
- 例子:新建一个类Person(抽象类不能生成对象)
反推:如果能生成抽象类对象的话,就能调用抽象类函数,如果 这样的话,抽象类函数没有函数体,就会出错(所以抽象类不能生成对象)!
如果生成了一个类不能调用,要这个类干嘛?
答:抽象类天生就是用来当爹的,只能用于继承。
新建一个类 Chinese 继承Person
-
新建一个类 Text
输出结果:
3).抽象类的特征
抽象类可以有构造函数吗?
条件:
-
抽象类不能生成对象。
-
构造函数用于生成类的对象。
可以有构造函数:但是为子类集成的时候用的,可以通过super(); 继承抽象类函数的构造函数。
证明:
例子:新建一个类Person(抽象类不能生成对象)
新建一个类 Chinese 继承Person
新建一个类 Text
输出结果:
结论:Person 这个类,虽然不能直接调用他的抽象函数的构造函数,但是抽象类的子类却可以通过super(); 调用父类的构造函数。
11.1为什么要使用抽象类
27.为什么要用抽象类?
- 抽象类是一个概念。
- 电脑也是一个概念,电脑也有很多种,笔记本电脑也是电脑,笔记本电脑相对于电脑更抽象一点。
- 就像前面有一个实例的打印机,都有打开,关闭,打印,但是打印机不同,打印方法就不同,具体方式不同,所以说 Printer 是抽象的,具体哪个打印机的打印是具体的HPPrinter 和 CannonPrinter .(可以定义一个抽象类 定义一个抽象的函数 abstract void Printer(); 然后通过在 类中HPPrinter和CannonPrinter 复写的具体方法)。
- 这种在生活中常常出现,比如汽车 ,“开”这个方法,有手动挡和自动挡,所以需要去定义一个抽象类,减少重复代码!
注意:如果 把一个类定义为抽象类,里面有一个抽象函数。如果需要继承这个父类,必须去复写这个函数,才能编译通过。
12.包和访问权限
包和访问权限
1).什么是Java 当中的软件包
1.软件包为Java类提供了命名的空间(两个类可以同名,但不同空间(文件夹))。
2.打包时需要使用package指令。
3.一个类的全名应该是“包名”+“类名”。
2).为什么要使用软件包
有两个软对分别开发,学生管理系统,和注册用户管理系统
团队A 团队B
——在分开测试的时候没有任何问题。但一旦合并使用就会出现重名的问题 。
解决方法:
1.可以使用不同的User 比如 Auser 和 Buser
2.使用软件包
12.1给一个类打包
3).如何给一个类打包
//将类放置到一个包当中,需要使用package+包名
//编译时需要使用 –d,该参数的作用是依照包生成相应的文件夹
//一个类的全名应该是”包名” + ”.” + “类名” yuan.Text 。
//即使进入到 yuan 文件夹,然后执行Text 也不行。
- 运行指令:javac -d . Text.java //-d依照包生成文件夹“.”代表当前目录
- 运行这条指令会生成yuan文件夹,生成一个 Text.class文件
- 运行指令:java yuan.Text。输出:打包
注意:即使进入yuan文件夹执行java Text 出错。只能运行整个类
——包名的命名规范
1.要求包名所有的字母都要小写
2.包名一般情况下,是你的域名倒过来写
12.2JAVA当中访问权限
4).Java当中的访问权限:
1.public : 公共权限
2.private: 私有权限
3.default: 包级别访问权限
4.protected: 受保护权限
总结:
1.public可以修饰成员变量和成员函数,没有任何限制,在不在同个包都可以 访问。
2.private 可以修饰成员变量和成员函数,只能在本类当中使用
3.default(不写权限修饰符,就是default 权限)可以修饰类、成员变量和成员函数,在同一个包可以*访问,不同不可以。
1).例子:
新建一个类Person.java
public 权限的作用是什么?
新建一个Text.java 的类。
编译:
此时编译没有问题,但是当去掉 Person 类的public 声明去掉。
再次编译:
出错,解释,如果一个类不是公共,那么在Text 类中就没有办法使用同一个类(前提:两个类不在同一个包中)。
2).例子:
新建一个类Person.java
新建一个Text.java 的类。
结论:(两个类在不同的包)一个类向访问另一类,被访问的类必须有public 权限,被访问的成员变量也必须有public权限。
2).private 权限
例子:新建一个类Person.java
新建一个Text.java 的类。
出错:结论:无论在不在同一个包里,如果声明为private ,只能在本类使用成员变量或者是成员函数。
3).default 包级别访问权限:什么都不声明就是default 权限
新建一个类Person.java
- 解析:如果Text 和Person 在同一个包当中,那么可以任意使用,使用生成对象调用类的变量问题。
- 注意:如果不在同一个包当中,还想访问Person 当中,在Text 中就不能访问了,除非 public 权限。
12.3如何导入一个包
如何导入一个包
例子:新建一个Text.java 的类。Person 的包在org.yuan 中
12.4包的访问权限和继承
5).访问权限与继承
1.如果父类和子类不在同一个包中,子类可以继承default 权限成员变量和成员函数,但是由于权限不够,无法使用。
2.如果希望一个包的变量和成员函数,被跨包继承的话,就需要给被继承的变量public权限。
1).新建一个类Person,给Person 打个包
2).新建一个Student 继承Person,给Student 打个包
6). protected 权限
1.protected 权限首先拥有和default 一样的功能,但是该权限只能修饰成员变量和成员函数。
总结:public > protected > default >private
13.Java 的接口(重点)
29. Java 的接口(重点)
1).什么是接口?
接口就是标准
2).接口的基本语法(一)
1.使用interface 定义
2.接口当中的方法是抽象方法(默认为 abstract(抽象方法),用来继承)。(用一个类用来继承接口,然后复写抽象函数)
3.接口当中的所有权限都是public权限
例子:(implements(实现)是特殊的继承)
2).接口的基本语法(二)
1.实现接口使用 implements 关键字。
2.一个类可以实现多个接口(手机可以用usb和WiFi功能)。(每个标准是一个接口)
3.一个接口可以继承多个接口。
例子:手机能用usb 跟电脑通信,又能用WiFi和电脑通信,所以这手机既支持usb接口,又支持WiFi接口。所以一个类可以实现(ipmlememts)多个接口.
实例 :建立一个接口称为 USB
再建立一个WIFI接口:
用 Phone 这个类去实现 USB和WiFi 接口
建立一个类Text 作为程序入口
3.为什么要使用接口?
工程方法模式:
例子:打印机,新建一个打印机(Printer)的接口,然后让(HPPrinter) 惠普打印机,和(Canon)打印机实现这个接口,然后通过Text作为程序的入口。
建立一个Text 的主程序入口调用
编译输出结果:
上面的Text 知识模拟一个设备而已,如果有多个设备,就会产生重复代码,而面向对象就是需要消除重复代码。那我们把重复代码打包成一个函数?
- 新建一个类 PrinterFactory
- 在Text中调用
- 如果多个设备调用只需调用:Printer printer = PrinterFactory.getPrinter(flag);如果增加了一个打印机,比如 xxxPrinter,我们只需要添加一个类,然后去实现Printer中的方法体(open 、close 、print),然后修改函数PrinterFactory 类,增加选项else if(flag == xx) 然后去实现,不需要修改Text文件,如果有多个设备调用打印机就可以避免重复代码。
14.JAVA当中的异常机制
14.1.什么是异常?
-
异常:中断了正常指令流的事件;是在程序运行的时候产生的(编译已经通过);
-
实例:异常是如何发生的?
一个简单的例子,语法没有错误:
但是在运行Text 的时候出现了异常(异常在运行产生)
再次修改,看是整个Text 不运行,还是被中断了:
可以看到“1”被打印出来,而 “2” 没有打印(说明是被中断)
14.2.异常的分类
异常的处理
小结:1.程序员对Error无能为力,只能处理Exception
2.对异常的处理关系到系统的健壮性能
3.使用 try...catch...finally 来处理可能出现的异常代码。
14.3.自定义异常
1.throw的作用:抛出一个异常
编译可以通过,但是运行出现错误:
我们修改一下User.java:
再次编译,编译没有办法通过:
小提示:
使用命令行编译运行java代码,编译时出现 “编码GBK的不可映射字符” 的错误提示,并且需输出的中文全部变为乱码,此时有两种解决方法:
(方法一)
在输入 javac 命令时,额外输入 -encoding utf-8, 例如:如果编译的源文件名为 Test.java ,那么编译时原先只需输入
javac Test.java,而现在需要输入 javac -encoding utf-8 Test.java
(方法二)
使用 EditPlus 软件编写代码时,通过修改相关设置然后保存文件即可,具体操作如下:
Document菜单---File Encoding---Convert Encoding...----ANSI,OK后保存文件 (需要保存文件,才能使设置生效),然后编译时就无需像(方法一)那样添加 -encoding utf-8 了,可以直接 javac Test.java
2.throws的作用 :声明一个异常
再次修改User.java
再次编译User.java,编译通过
编译 Text.java时出现问题
这时我们就可以用 try..catch 来处理异常了:
15.JAVA的IO系统
15.1.I/O操作的目标
- 从数据源当中读取数据,以及将数据写入到数据目的地当中
15.2.IO的分类方法
第一种分发:
1.输入流
2.输出流
第二种分发:
1.字节流
2.字符流
第三种分发:
1.节点流
2.处理流
I/O当中的核心类:
15.3.读取文件和写入文件的方法
核心类的核心方法 :
字节流方法函数:
ImputStream:
int read(byte[ ]b,int offset, int len) ------>返回读取的读取的字节数,读完数据返回:-1
OutoutStream:
void Write(byte[ ]b,int offset,int len)
例子:
新建一个文档:from.txt 和 to.txt
from.txt的内容为,路径为 g:/src/from.txt:
15.4.读取数据的方法(字节流):
运行Text.java :
把数字转换成字符:
运行结果:
15.5数据的写入方法(字节流):
新建一个 to.txt ,文本为空,路径为 g:/src/to.txt.
运行后查看 to.txt:
小结:1.I/O系统的主要目标是为了对数据进行读写操作。
2.数据的流向以Java程序为参照物。
3.I/O可以有三种分类方法。
4.read方法和write方法的用法。
15.6.大文件的读写方法
1. 改写from.txt:
修改Text.java,把from.txt的大文件,读取到to.txt中。
运行后,to.txt文本内容和from文本内容一模一样。
15.7.字符流的使用方法
字符流方法函数:
字符流:读写文件时,以字符为基础
字节输入流:Reader <-- FileReader
int read(char [] c,int offset,int len)
字节输出流:Writer <--FileWriter
void Write(char [] c,int offset,int len)
15.8.节点流和处理流
1.处理流使用实例
BufferedReader对象的使用方法:
运行Text.java
2.装饰者(Decorate)模式
假如使用继承的话我们实现以下功能就会需要一个父类工人(Worker) 用然后水管工(Plumber)和木匠(Carpenter)去实现(implements)工人(Worker) 这个接口 ,然后再用(A公司水管工 )和(B公司水管工 )去都实现水管工(Plumber)这个类,木匠也一样采用继承的方式。目前看似我们建立的类并不多,但我们如果还有电工、水泥工等工总,还有C公司、D公司等公司,类的数量就会成几何增长,没增加一个工总和公司,增加的类就会很多,代码就会变得冗杂。
那我们如何简化这个程序?使用装饰者模式,我们用实例说明:
1.建立一个Worker的父类接口:
2.建立Plumber(水管工)和Carpenter(木匠)去实现工人(Worker)这个接口:
3.接下来就到了精髓的地方了,建立一个Aworker(A公司工人) 这个类也去实现Worker(工人),这样一来水管工(Plumber)、木匠(Carpenter)、和A公司员工(Aworker)全部是 工人(Worker)的子类了,我们同样去实现Worker(工人)这个接口:
4.建立一个 Text01.java 作为程序入口:
我们试运行一下 Text01.java:
目前我们只用了一个接口,三个类就实了A公司的功能(采用继承我们需要的是4个类),看起来好像也差不多?但是我们增加一个公司呢,使用装饰者模式,只需要增加一个类Bworker(采用继承增加两个类,随着工总和公司的增多增加类的数目成倍增长),而使用装设者模式就可以大大简化程序。
细心的可以我们前面使用处理流的时候使用的就是装饰者模式,我们再看看程序:
FileReader 本来只能是几个字节的读取,但是有了bufferedReader之后,就可以一行一行来读取数据,其实就是在FileReader 之上加了新的功能。所以bufferedReader不仅可以修饰FileReader还可以修饰来自键盘和网络的数据!
3.节点流和处理流之间的关系
处理流是用来装饰节点流的,节点流是被装饰者,处理流是装饰者,处理流在为节点流在基础的功能上,添加新的功能。
16.内部类和匿名内部类
16.1.什么是内部类?
编译A.java这个文件,会产生两个类文件
如何生成内部类文件的对象?
编译结果验证了内部类可以随意调用外部类的成员变量和成员函数:
16.2.匿名内部类
例子1:
采用正常的方法,使用装饰者模式:
用Text.java生成 B类的对象,调用成员函数:
运行Text.java
这是正常的逻辑。
例子2:采用匿名内部类的方法
运行的结果也是一样的,只不过,这个生成的类是没有名字的,而且是在别的类里面的类,所以称为 “匿名内部类”。
再看下面一个实现Rnanable接口的例子:不使用匿名内部类方法如下:
使用匿名内部类的方法,一对比就很容易看出端倪啦:
17.JAVA 当中的线程
17.1.进程和线程
多线程和多进程?
多进程:在操作系统中能(同时)运行多个任务(程序)。
多线程:在同一应用程序中有过个顺序流(同时)执行。
一个应用程序有一个进程,一个进程有多个线程。
注意:线程也是一个对象。有对象就有生成对象的类。
17.2.线程的创建方法
- 实现线程方法一:定义一个线程类,它继承类 Thread 并复写其中的方法 run(),方法 run( ) 称为“线程体” (由于Java只支 持单继承,用这种方法定义的类不能再继承其 他的类)。
注意:如果上面调用的不是 ft.start( )方法,而是执行ft.run( )就不是多线程,而是单线程运行,结果是:先执行 FirstThread ---->0 -100 然后再执行 main---->0 - 100。
运行Text.java,两个线程无规律运行,谁抢占到CPU使用权,就是谁运行:
- 实现线程方法二(常用):提供一个实现接口 Runnable 的类作为线程的目标对象,在初始化一个Thread类或者Thread子类的线程对象时,把目标对象传递给这个线程实例,由该目标 对象提供线程体。
下面采用实例演示:
运行Text.java:
17.3.线程的简单控制方法:
中断线程:
——Thread.sleep( x ms); //睡眠醒了进去就绪态,不一定运行
——Thread.yiled(); //当前线程自动让出CPU,但是此线程还会去抢cpu使用权
设置线程的优先级:
——getPriority(); //得到当前线程优先级
——setPriority(); //设置当前线程优先级
17.4.多线程程序运行模式
1.多线程数据安全
例子:多线程数据访问出错:
建立一个类 MyThread去实现Runnable 接口:
建立Text.java去调用线程运行:
运行Text.java
如果是卖火车票的话这个数据访问就会出现很大的问题。
如何解决这个问题呢?
使用同步代码块: synchronized( this ) { }
运行:前面的问题解决,但是出现新的问题,我们后续解释:
17.5.深入理解synchronized关键字:
例子:新建一个类 Service.java,这个类有两个函数,全部有同步代码块,且程序会从funA()开始运行,那么就会进去休眠,且这个 this 对象被锁住,在休眠期间,funB也没有办法执行,只有等到funA()执行结束,才会轮到funB,所以说同步代码块,锁住的是对象,而不是特定某一段程序。
再新建两个实现类(MyThread1和MyThread2)去实现Runnable接口(实现线程的第二种方法):
新建Text.java 作为程序入口:
运行程序Text.java,执行java Text 语句后,程序休眠4s,才打印输出以下结果,说明funA()和funB全部被锁住了,更加说明了,同步代码块锁住的是 service 这个对象:
为了进一步验证,我们把,funB() 里面的同步代码块去掉,看程序运行结果:
执行结果,程序一开始就打印出了 ”执行 funB 函数“,然后过4s后才打印 ”执行 funA 函数“,没有加控制代码块的线程,正常运行,不受其他任务控制代码块的影响:
18.JAVA数组(一维和二维)
18.1.数组的类型
18.2数组的定义方法
18.3数组的操作方法
1.一维数组静态定义方法:
2.动态方法:
3.二维数组定义方法:
19.JAVA的类集框架
19.1.什么是类集框架?
1.类集框架是一组类和接口
2.放置于java.util包当中
3.主要用户存储和管理的对象
4.主要分为三大类:集合、列表和映射
19.2.集合的种类:
集合(一种存储数据的方式)中的对象不安特定的方式排序,并且没有重复对象。
列表:集合中对象按照索引位置排序,可以有重复的对象
映射 :集合中的每一个元素包含一个键对象和一个值对象,键不可重复,值可以重复。
19.3类集框架的基础结构
从上面的集合框架图可以看到,Java 集合框架主要包括两种类型的容器,一种是集合(Collection),存储一个元素集合,另一种是图(Map),存储键/值对映射。Collection 接口又有 3 种子类型,List、Set 和 Queue,再下面是一些抽象类,最后是具体实现类,常用的有 ArrayList、LinkedList、HashSet、LinkedHashSet、HashMap、LinkedHashMap 等等。
例子:
列表方法:
1.arrayList.add(参数1 ) //向列表添加数据,参数是需要添加的数据
2.arrayList.remove(参数1) //参数是需要移除数据的索引号
3.arrayList.size() //得到当前列表长度
import java.util.List; //导入包
import java.util.ArrayList;
class Text{
public static void main(String args[]){
//生成ArrayList对象
//和数组不同的是,这个列表不是固定死的长度
//根据你的数据大小调节
//ArrayList<String> 表示列表只能存放Sring类型数据
ArrayList<String> arrayList = new ArrayList<String>();
//向 arrayList 列表添加数据,用 arrayList.add()方法
arrayList.add("a");
arrayList.add("b");
arrayList.add("c");
arrayList.add("d");
//使用arrayList.remove() 方法去除列表的数据
arrayList.remove(2); //参数为索引号,去掉"c"
//取出 arrayList 列表的数据,用arrayList.get()方法
//用 arrayList.size()方法可以获取列表长度
for(int i=0;i<arrayList.size();i++){
String s = arrayList.get(i); //参数为索引号
System.out.println(s);
}
}
}
运行结果Text.java:
19.4.Collection和Iteractor(迭代器)接口
Collection接口
boolean add(Object o) |
向集合加入一个对象 |
void clear( ) |
删除集合当中所有对象 |
blloean isEmpty( ) |
判断集合是否为空 |
remove(Object o) |
从集合中删除一个对象的引用 |
int size( ) |
返回集合元素的数目 |
-
Set(集合)与HashSet(Set的实现类)的使用方法:
-
Set是Collection的子接口。
一个 例子演示函数用法:
注意:Set 不允许有重复元素,重复的话会被忽略掉
import java.util.Set;
import java.util.HashSet;//导入包
class Text{
public static void main(String args[]){
//<String>称为泛型的声明
HashSet<String> hashset = new HashSet<String>();
//把HashSet的对象向上转型
//子类 HashSet的对象,赋值给父类Set的引用
Set<String> set = hashset; //只能调用Set有的方法
//使用set的方法,增加集合成员
set.add("a");
set.add("b");
set.add("c");
set.add("d");
set.add("d"); //重复元素,被忽略
//集合的个数
int i = set.size();
System.out.println("clear之前set对象的长度"+i);
//清空集合
set.clear();
//再次获取集合个数
i = set.size();
System.out.println("clear之后set对象的长度"+i);
}
}
运行Text.java结果:
2.Iteractor(迭代器)接口
import java.util.Set;
import java.util.HashSet;//导入包
import java.util.Iterator;//导入迭代器包
class Text{
public static void main(String args[]){
//<String>称为泛型的声明
HashSet<String> hashset = new HashSet<String>();
//把HashSet的对象向上转型
//子类 HashSet的对象,赋值给父类Set的引用
Set<String> set = hashset; //只能调用Set有的方法
//使用set的方法,增加集合成员
set.add("a");
set.add("b");
set.add("c");
set.add("d");
set.add("d"); //重复元素,被忽略
//调用Set对象的Iteractor方法,会生成一个迭代器对象,该对象用于遍历整个Set
//需要使用泛型声明
Iterator<String> it = set.iterator();
// 使用it.hasNext() 方法返回一个bollean类型数值
while(it.hasNext()){
//使用it.next()方法获取游标下一个元素的值
String s = it.next();
System.out.println(s);
}
}
}
19.5.Map与HashMap的使用方法
映射 (Map):集合中的每一个元素包含一个键对象和一个值对象,键不可重复,值可以重复。
注意:JdK API帮助文档是我们非常重要的工具,里面详细介绍了API函数的用法。
在线帮助文档地址:点我查看JDK帮助文档
我们看一看Map的帮助文档,里面的解释非常详细和权威:
最重要的方法摘要:
咋们用一个简单的例子,调用一下这个函数:
import java.util.Map;
import java.util.HashMap;
class Text{
public static void main(String args[]){
//指定泛型,两个对象,键值对,两个对象
HashMap<String,String> hashMap = new HashMap<String,String>();
//向上转型为Map类型
Map<String,String> map = hashMap;
//就可以使用map的put方法了
map.put("1","a");
map.put("2","b");
map.put("3","c");
map.put("4","d");
map.put("3","f"); //键值没有办法重复,键值为3的值会被"f"覆盖
//使用map.size()方法返回此映射中的键-值映射关系数。
int i = map.size();
System.out.println(i);
//使用map.get()方法,返回指定键所映射的值;
//如果此映射不包含该键的映射关系,则返回 null
String s = map.get("3");
System.out.println(s);
}
}
运行Text.java:
20.equals函数
20.1.equals函数在什么地方
我们可以在java安装的文件夹里的 Object.java中找到 equals函数的原形
20.2.equals函数的作用:
那么在 equals函数中“==”的作用是什么?
操作符的作用:判断这个两个引用是否指向堆内存当中的同一个地址 (对象)
例子1:
调用equals函数,:
如果没有去复写 equals函数 ,和直接调用 “==”是完全一样的:
注意:User已经是继承了Object的
运行结果和我们预想的一样:
小结:如上所述,如果这个原型equals( ) 函数只能去判断,两个引用是否指向同一个对象,如果指向同一个对象就返回 ture,否则返回 false.而并不能去比较在同一个类指向不同对象的内容是否相等。像上图所示,虽然 u1指向的对象和 u3指向的对象内容是一样的,但是在堆内存中指向的不是同一个对象,随意判定为 false.
例子2:我们试一下比较,指向不同对象,但是内容相同的对象,进行比较,看是否能得到我们想要的结果:
运行Text.java,可见和我们预想的一样,一旦指向不同对象,不管你的内容是否一样,我都返回false:
在实际应用中我们往往需要去复写equals函数,去判断对象的内容是否相等:
什么是对象的内容相等?
1.对象的类型相同(可以使用instenceof操作符进行比较)。(比如是否都为 User类,如果类不同,肯定不能比较了)。
2.两个对象的成员变量的值完全相同(比如在User类有两个变量 name 和 age)。
我们依照这两个条件在User.java中复写这个 equals() 这个方法:
class User{
String name; //因为 String是引用数据类型,不能用equals进行比较内容,
int age; //基本数据类型用 “==” 进行比较
//复写 equals 函数
public boolean equals(Object obj){
//this 就是调用equals函数的那个对象
//谁能调用这个equals呢?属于User这个类,this就是User类型的。
//所以只有User类的对象可以调用equals这个函数
if(this == obj){ //如果在堆内存中指向同一个对象,内容一定相等
return true; //直接返回真
}
//那 obj 是属于User类型的吗?
//instanceof 关键字用于判断前面的对象是不是后面的那种类型
//是的话返回真,否返回假
boolean b = obj instanceof User;
if(b){ //那么说明obj也是User类型
//那么需要把 obj 向下转型为 User的对象
//向下转型,能成功,因为我们知道 obj 这个对象是 User这个类生出的
//在前面这个 obj 之所以是 Object 类型,是因为有过一次向上转型
//现在把它转回来也是 ok 的
User u = (User)obj;
//接下来判断 u 对象和 this 他们成员变量的值是否相等
//这里调用的 String类型equals()方法不是本函数的
if(this.age == u.age && this.name.equals(u.name)){
return true; //那就是相等的
}
else{
return false;
}
}
else{
return false; //如果不是的话,就不用比较了
}
}
}
然后在Text.java 引用3个创建 User 的对象进行比较内容:
class Text{
public static void main(String args[]){
//创建u1、u2、u3的引用
User u1 = new User();
User u2 = new User();
User u3 = new User();
u1.name = "zhangsan";
u1.age = 12;
u2.name = "lisi";
u2.age = 12;
u3.name = "zhangsan";
u3.age = 12;
System.out.println("u1和u2的比较结果是:" + u1.equals(u2));
System.out.println("u1和u3的比较结果是:" + u1.equals(u3));
}
}
运行Text.java,输出结果:
- 所以没有去复写 equals() 函数,功能和“==” 是一样的,只能比较这两个对象是否指向堆内存的同一个地址。
- 小结:现在我们只需要了解复写 equals函数的方法,在后期开发当中,我们更多使用开发工具,帮我们自动生成equals 方法。
21.hashCode 和 toString方法(继承Object)
1.hashCode()的作用
什么是Hash算法?
Hash算法的特点,可以根据唯一的散列值直接找到输入:
2.hashCode()的实现方法
- 我们用一个简单的例子:
- 在复写equals函数的基础上,增加两个构造函数,修改User.java函数:
class User{
String name;
int age;
//新增两个构造函数
public User(){
}
public User(String name,int age){
this.name = name;
this.age = age;
}
public boolean equals(Object obj){
if(this == obj){
return true;
}
boolean b = obj instanceof User;
if(b){
User u = (User)obj;
if(this.age == u.age && this.name.equals(u.name)){
return true;
}
else{
return false;
}
}
else{
return false;
}
}
}
- 然后修改Text.java类,如下,new User("zhangsan",20) 和 u 的内容用equals比较的结果为true:
import java.util.*; //导入包
class Text{
public static void main(String args[]){
User u = new User("zhangsan",20);
//声明HashMap对象,指明泛型为<User,String>
HashMap<User,String> map = new HashMap<User,String>();
//向map对象put
map.put(u,"abcd");
//用equals比较new User("zhangsan",20)和 u 的结果应该为true
System.out.println("比较结果是:" + new User("zhangsan",20).equals(u));
//根据键得到值
String s =map.get(new User("zhangsan",20));
System.out.println(s);
}
}
- 运行Text.java,可见,虽然比较结果一样,输入键值new User("zhangsan",20) 却找不到一个值对应,就是说没有找到对象的Hash码,因为键值对不是通过比较对象的内容,而是通过计算对象的HashCode去配对键值对:
- 然而我们并没有去复写User.java 里面的HashCode方法,而是用默认的,则是继承过来的。按照逻辑来说我们应给认为相同的对象都认为同一个键,那我们去复写User里面的HashCode的方法。 修改User.java
class User{
String name;
int age;
//新增两个构造函数
public User(){
}
public User(String name,int age){
this.name = name;
this.age = age;
}
public boolean equals(Object obj){
if(this == obj){
return true;
}
boolean b = obj instanceof User;
if(b){
User u = (User)obj;
if(this.age == u.age && this.name.equals(u.name)){
return true;
}
else{
return false;
}
}
else{
return false;
}
}
//对于不同的对象生成hashcode的数值是不一样的
//对于用equals相比结果为ture的对象来讲hashCode是一样的
//因为为true则,name和age肯定是一样的,那么返回result的值肯定是一样的
public int hashCode(){
int result = 17; //初始值为除0外的素数
result = 31 * result + age;
result = 31 * result + name.hashCode(); //调用String的hashCode方法
return result;
}
}
- 修改Text.java:
import java.util.*; //导入包
class Text{
public static void main(String args[]){
User u = new User("zhangsan",20);
//声明HashMap对象,指明泛型为<User,String>
HashMap<User,String> map = new HashMap<User,String>();
//向map对象put
map.put(u,"abcd");
//用equals比较new User("zhangsan",20)和 u 的结果应该为true
System.out.println("比较结果是:" + new User("zhangsan",20).equals(u));
//根据键得到值
String s =map.get(new User("zhangsan",20));
System.out.println("得到的键值为:"+s);
}
}
- 运行Text.java,因为hashCode被复写了,对象 u 和:new User("zhangsan",20) 得到相同hashCode,所以键值对能够匹配,跟equals函数相同,后期我们大多都是用软件自动生成代码的:
3.toString()的作用
- Java当中的toString函数
以下代码的运行结果:System.out.println("abc") ------>打印 abc 字符
- 其实toString是Object类的函数,意味着所有的类都继承了这个函数,所以都能进行复写!
那么下面两行呢?
User u = new User();
System.out.println(u);
- 以上代码执行的时候,实际是调用u的toSring方法。我们是实例看一下:
4.toString()实现方法
- 那我们在User.java中复写一下toString方法:
- 修改User.java如下:
class User{
String name;
int age;
//新增两个构造函数
public User(){
}
public User(String name,int age){
this.name = name;
this.age = age;
}
public String toString(){
String s = "name:"+name+", age:"+age;
return s;
}
}
- 修改Text.java,如下:
import java.util.*; //导入包
class Text{
public static void main(String args[]){
User u = new User("zhangsan",20);
//当你打印一个字符串的时候,首先会调用这个类的toSring方法
System.out.println(u);
}
}
- 运行Text.java:
22.Java开发工具(Eclipse)
- Eclipse官方网站:点我
- 下载Eclipse:
- 下载完成后,直接解压就能使用:
- 打开后选择工作空间(workspace)
22.1.Eclipse的基本概念
-
工作区(workspace)
工作区是一个目录,程序和程序所需要用到的资源都在workspace里,中间缓存文件也存在工作区中。
-
项目(Project)
为一个需求所服务的代码文件,一个workspace 可以拥有个项目,而你的代码必须有归属于某个项目的,不能单独存在。
22.2.Eclipse创建Java文件
-
首先,创建项目,弹出一个窗口:
- 填写项目名字,点击finish:
- 创建完成后:
- 创建一个类之前先创建一个包(为了易于管理),和我们前面讲到的打包是一样的,链接:包和访问权限:
- 创建一个包(package):
- 在包中新建类:
- 填写类名,类的属性:
- 然后创建Text.java自动,添加一些我们需要的东西,和我们用Nodepad++,编辑的源文件是一样的,我们打了个包,然后穿件一个 public 权限 的 Text类文件,然后自动添加main 入口函数,只是这些Eclipse帮我们做好了:
- 我们随便打印一句话:Hello World!
- 接下来我们就是,编译、运行了,Eclipse已经集成这个功能了,其实当你打好代码,保存的时候Eclipse已经自动帮你编译,生成class文件了(语法正确),那存放的位置呢: 我们可以在我们创建的工作空间(workspace)找到我们创建的包和类文件:
- 那么生成类文件了,就可以运行了,实际运行的是class文件:
- 下方窗口直接显示输出结果:
- 想在这个工程包中新建新的类和接口,如何做?,我们新建一个接口 Person然后用Student 去实现Person这个接口:
- 创建接口Person,两个方法:
- 新建一个类 Student去实现Person 这个接口,方法和上面一样,然后再interface去选择所需要实现的接口:
- 我们可以发现,Eclipse不仅帮我们写了实现代码,还对父类的抽象方法进行复写:
Eclipse调试错误功能也很强大:
22.2.eclipse 代码提示功能
- 例如编辑: System.out.println( ); 会出现很多提示:
- 编辑我们刚刚的 Student.java 文件,声明一个 Student 的引用 st,也同样会出现代码提示.
22.3.快捷键的使用:
- 删除一行的程序:把光标放在要删除的哪一行,使用快捷键: Ctrl + D
- 剪切 : Ctrl + X
- 撤销上一次操作: Ctrl + Z
- 重新执行之前的命令:Ctrl + Y
-
Alt + "/" 快捷键的用法:
此时如果我还想生成一个Student的对象,但是写到一半,不想写了,我们直接使用快捷键:会弹出提示窗口,显示所有以stu开头的函数:
我们可以在 Edit菜单栏可以看到快捷键:
22.4.代码自动生成功能:
例子:我们编辑Student.java 文件如下,我们新建了三个成员变量,现在我们想新建两个构造函数,一个是无参数构造函数,一个是带三个参数的构造函数,如何让Eclipse 自动帮我们去生成呢:
- 下图显示了基本的操作:
- 生成构造函数:
操作上面的结果是:
- 生成equals函数和hashCode函数:
很方便就帮我们复写了这两个函数:
22.5.代码注释
选中需要注释的代码,然后快捷键:Ctrl + "/".
取消注释:选中已经被注释的代码,同样快捷键:Ctrl + "/"
22.6.代码重构(重点)
1.在别改变代码功能和性能的基础上。
2.改善软件的设计增加可读性
3.协助找到bugs
4. 提升开发效率
1.修改类名
例子:在以下工程中,我们如果想改变Person的为Teacher,怎么办呢?
如果手动改动的话,麻烦不说,只有有一个地方忘了程序就会出现错误,降低了开发效率,但是我们可以使用Eclipse代码重构功能。
- 开始重构
- 下一步
- Next:
- 完成
2.移动:如何把一个包里面的类或接口移动到另一个包呢?
- 首先,新建一个包,命名为:org.yuan.my_project.modle
- 第一步
- 第二步
- 完成
3.修改方法签名:
例子:比如我们在Student.java中创建了一个函数 ,void speak() 然后在 void eat() 中调用,突然我们想改变speak为talk,如果多个地方调用这个方法的话就会很麻烦,我们用Eclipse修改方法签名就会很简单:
- 修改
- 下一步:
- 完成:
如果此时我们想把 talk( )函数推到Teacher(父类)中,怎么办?
- 操作如下:
- 下一步:
- 查看Teacher.java,函数,增加了talk() 的抽象函数:
4.抽取类功能:把在一个类的方法,给抽到另一类当中
例子:我们把 Student中的抽取 talk方法和eat 方法,抽成父类,抽好了以后,Student,应给去继承有着两个函数的类或者接口。
- 填写参数
- 看结果:
在Person.java中已经有着两个方法了:
在Student.java中没哟这两个方法了:
也可以抽取成毫无关系的类。
5.抽取方法:减少重复代码
例子:如下、
我们不希望重复代码,我们可以把这两句抽成一个方法,然后别的函数再调用这个方法:
- 下一步:
- 完成