目录
1. 面向对象思想
1.1 面向对象思想概述
面向对象是基于面向过程的编程思想
- 面向过程:强调每一个功能的步骤
- 面向对象:强调的是对象,然后由对象去调用功能
1.2 面向对象思想的特点
- 是一种更符合我们思想习惯的思想
- 可以将复杂的事情简单化
- 将我们从执行者变成了指挥者,角色发生了转换
1.3 面向对象开发、设计、特征
面向对象开发
就是不断的创建对象,使用对象,指挥对象做事情。
面向对象设计
其实就是在管理和维护对象之间的关系。
面向对象特征
- 封装(encapsulation)
- 继承(inheritance)
- 多态(polymorphism)
2. 类与对象及其使用
2.1 类与对象概述
类:
- Java语言最基本单位是:类
- 用类来体现现实世界的事物;
- 事物:属性(该事物的描述信息)和 行为(该事物能做什么)
- 类:成员变量 和 成员方法(功能)
类:是一组相关的属性和行为的集合(eg:学生)
对象:是该类事物的具体表现形式,具体表现个体(eg:班长)
2.2 类的定义及分析
定义一个类,其实就是定义该类的成员变量和成员方法。
- 定义成员变量 和以前定义变量是一样的,只不过位置发生了改变。在类中,方法外
- 定义成员方法 和以前定义方法是一样的,只不过把static去掉,后面再详细讲解static的作用
案例1:完成一个学生类的定义
学生事物:
- 属性:姓名,年龄,地址
- 行为:学习,吃饭,睡觉
转换成学生类:
- 成员变量:姓名,年龄,地址
- 成员方法:学习,吃饭,睡觉
代码实现:定义一个学生类
//定义一个学生的基本类,只是指定义了一个类,代码不完整不能运行
class Student {
//成员变量的定义位置在类中,方法外
//定义姓名
String name;
//定义年龄
int age;
//定义地址
String address;
//定义方法
//学习的方法
public void study(){
System.out.println("学Java");
}
//吃饭的方法
public void eat(){
System.out.println("饿了要吃饭");
}
//睡觉的方法
public void sleep(){
System.out.println("累了要睡觉");
}
}
2.3 类的使用
注意:
- 在一个java文件中写两个类,一个基本类,一个测试类
- 文件名称和测试类一致
案例1:定义并使用一个学生类
//定义一个学生的基本类
class Student {
//成员变量的定义位置在类中,方法外
//定义姓名
String name;
//定义年龄
int age;
//定义地址
String address;
//定义方法
//学习的方法
public void study(){
System.out.println("学Java");
}
//吃饭的方法
public void eat(){
System.out.println("饿了要吃饭");
}
//睡觉的方法
public void sleep(){
System.out.println("累了要睡觉");
}
}
//定义一个学生的测试类
class StudentDemo{
//要想运行测试必须写main方法
public static void main(String[] args){
//学生类 使用类需要创建对象
//创建对象格式:类名 对象名 = new 类名();
Student s = new Student();
//使用成员变量:对象名.变量名
//输出成员变量
System.out.println(s.name);
System.out.println(s.age);
System.out.println(s.address);
System.out.println("--------");
//给成员变量赋值
s.name = "卡卡西";
s.age = 3;
s.address = "木叶村";
System.out.println(s.name);
System.out.println(s.age);
System.out.println(s.address);
System.out.println("--------");
//调用方法:对象名.方法名(参数)
s.study();
s.eat();
s.sleep();
}
}
2.4 对象的内存图
- 一个对象的内存
- 两个对象的内存
- 三个对象的内存
3. 成员变量和局部变量的区别
3.1 在类中的位置不同
- 成员变量:在类里面,方法外面
- 局部变量:在方法定义中(方法里面)或在方法声明上(方法的小括号里)
3.2 在内存中的位置不同
- 成员变量:在堆内存中
- 局部变量:在栈内存中
3.3 生命周期不同
- 成员变量:随着对象的创建而存在,随着对象的消失而消失
- 局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
3.4 初始化值不同
- 成员变量:有默认初始化值(byte,short,int,long——0;float,double——0.0;char——\u0000;boolean——false)
- 局部变量:没有默认的初始化值,必须先定义,赋值,才能使用
注意:成员变量和局部变量的名称可以相同,在方法中采用就近原则
形式参数的问题:
基本类型:形式参数的改变不影响实际参数
引用类型:形式参数的改变直接影响实际参数
案例2:创建并使用一个形式参数为基本类型的类
//形式参数是基本类型
//创建一个形式参数为基本类型的基本类
class Demo{
//写sum方法并用return返回一个明确值
public int sum(int a,int b){
return a + b;
}
}
//创建一个形参为基本数据类型的测试类
class DemoTest{
//main方法保证程序运行
public static void main(String[] args){
//创建对象格式:类名 对象名 = new 类名();
Demo d = new Demo();
//调用方法,调用格式:对象名.方法名(参数)
int result = d.sum(12,20);
System.out.println(result);
}
}
案例3:创建并使用一个形式参数为引用类型的类
//形式参数是引用类型
//创建一个学生类
class Student{
//学生类中创建一个show方法
public void show(){
//show方法的功能
System.out.println("学习Java");
}
}
class StudentDemo{
//创建一个method方法,参数列表为Student s
//Student是一个类,类是引用数据类型
//s是Student中的一个对象
public void method(Student s){ //调用的时候将main方法中s的地址值传递到了这里
//通过Student类中的s对象调用show方法,
s.show();
}
}
//需求:调用StudentDemo类中的method方法
class DemoTest1{
public static void main(String[] args){
//要调用首先要在类中创建一个对象
StudentDemo sd = new StudentDemo();
//通过创建的对象调用method方法,调用格式:对象名.方法名(参数)
//由于这里的参数是一个引用参数(Student类),需要的其实是该类中的对象,所以应该先在Student类中创建一个名为s的对象
Student s = new Student();//此时生成了s的地址值
sd.method(s);//把s的地址值给了这里
}
}
4. 匿名对象
4.1 概述
匿名对象,就是没有名字的对象,是对象的一种简化表现形式
4.2 匿名对象的两种应用场景
1. 调用方法,且仅仅调用一次的时候
好处:调用完毕就是垃圾,可以被垃圾回收器回收,提高内存使用效率
注意:不适用于多次调用。使用这种方法多次调用时不是调用同一对象而是重新创建了一个新的对象
2. 作为实际参数传递
5. 封装(private)
案例4:
//定义一个学生类
//成员变量:name,age,在类中方法外
//成员方法:show()方法
//定义一个学生基本类
class Student{
//首先定义成员变量
String name;
//private int age;//被private修饰的成员变量不能直接赋值
int age;//可以直接赋值
//在基本类中写一个数据校验方法,即setAge()方法,在给成员变量赋值的时候调用
//两个明确——返回值类型:void;参数列表:int
public void setAge(int a){
if(a < 0 || a > 120){
System.out.println("你输入的年龄有误");
}else{
age = a;
}
}
//写一个show()方法,显示所有成员变量值
public void show(){
System.out.println(name+":"+age);
}
}
//学生测试类,测试类一般只创建对象,调用方法
class StudentDemo{
public static void main(String[] args){
//创建对象
Student s = new Student();
//通过对象调方法显示成员变量的值
s.show();
System.out.println("------");//输出的默认值 null:0
//通过对象s直接给成员变量赋值
s.name = "小丸子";
//s.age = 5;
//通过对象S调用show()方法输出
s.show();
System.out.println("------");//输出的值 小丸子:5
/*
通过对象赋给成员变量的值可能不合理,在赋值之前需要对数据进行判断;
由于测试类只创建对象和调用方法,所以数据校验应该在基本类中;
又由于数据校验需要依靠逻辑语句,逻辑语句是定义在方法中的,
所以不能在定义成员变量的时候校验数据。
*/
//给成员变量赋值
s.name = "小丸子";
//调用setAge()方法赋值
s.setAge(6);
//调用show()方法输出信息
s.show();
System.out.println("------");//输出的值 小丸子:6
//给成员变量赋值
s.name = "小丸子";
//调用setAge()方法赋值
s.setAge(-5);
//调用show()方法输出信息
s.show();
//输出的值:你输入的年龄有误 小丸子:6
//这里的6是上一段通过setAge()赋的值,存在堆内存中
}
}
上述案例中,只有调用setAge()方法才会对成员变量的赋值数据进行检验,如果不调用方法直接赋值,就无法进行校验的步骤,无法保证数据的合理性。为了强制不能直接对成员变量赋值,可以使用Java提供的关键字 private 对成员变量和成员方法进行修饰。
注意:被private修饰的成员只能在本类中访问
5.1 概念
是指隐藏对象的属性和实现细节,仅对外提供公共访问方式
5.2 封装的好处
- 隐藏实现细节,提供公共的访问方式
- 提高了代码的复用性
- 提高安全性
5.3 封装原则
- 将不需要对外提供的内容都隐藏起来
- 把属性隐藏,提供公共方法对其访问
5.4 private关键字
概述
- 是一个权限修饰符,可以修饰成员(成员变量和成员方法)
- 被private修饰的成员只在本类中才能访问(在本类中提供一个公共方法来访问)
private关键字的应用
案例5:
/*
private关键字最常见的应用
1. 把成员变量用private修饰
2. 提供对应的getXxx()/setXxx()方法
3. 一个标准的案例的使用
*/
//创建一个学生基本类
class Student{
//定义成员变量
private String name;
private int age;
//获取姓名
public String getName(){
return name;
}
//赋值姓名
public void setName(String n){
name = n;
}
//获取年龄的方法
public int getAge(){
//返回一个值
return age;
}
//赋值年龄的方法
public void setAge(int a){
age = a;
}
}
//创建一个测试类
class StudentTest{
//main方法保证程序运行
public static void main(String[] args){
//在Student类中创建一个对象
Student s = new Student();
//使用成员变量
//System.out.println(s.name+":"+s.age);直接访问name和age报错
//System.out.println("--------");
//通过对象调用赋值姓名方法给成员变量name赋值
s.setName("旗木卡卡西");
//通过对象调用赋值年龄方法给成员变量age赋值
s.setAge(3);
//通过获取方法得到值并打印出来
System.out.println(s.getName()+":"+s.getAge());
System.out.println("--------");
}
}
5.5 this关键字
this:代表所在类的对象引用
注意:方法被哪个对象调用,this就代表那个对象
this关键字的使用场景:
- 局部变量隐藏成员变量
- 其他用法后面和super一起讲解
案例6:
//创建一个学生基本类
class Student{
//定义成员变量
private String name;
private int age;
//获取姓名
public String getName(){
return name;//这里其实隐含了this
}
//赋值姓名
public void setName(String name){
this.name = name;//方法被Student类中的s调用,这里的this就代表对象S
}
//获取年龄的方法
public int getAge(){
//返回一个值
return age;
}
//赋值年龄的方法
public void setAge(int age){
this.age = age;//方法被Student类中的s调用,这里的this就代表对象S
}
}
//创建一个测试类
class StudentTest1{
//main方法保证程序运行
public static void main(String[] args){
//在Student类中创建一个对象
Student s = new Student();
//使用成员变量
//System.out.println(s.name+":"+s.age);直接访问name和age报错
//System.out.println("--------");
//通过对象调用赋值姓名方法给成员变量name赋值
s.setName("旗木卡卡西");
//通过对象调用赋值年龄方法给成员变量age赋值
s.setAge(3);
System.out.println(s.getName()+":"+s.getAge());
System.out.println("--------");
}
}
6. 构造方法
6.1 构造方法的作用
给对象的数据进行初始化
Student s = new Student();//这里的Student()就是一个构造方法
案例7:
//系统自动提供的构造方法
class Student{
//这里系统自动提供了一个无参构造方法:默认修饰符 类名(){}
/*
Student(){
}
*/
}
class ConstructDemo{
public static void main(String[] args){
//创建对象
Student s = new Student();
System.out.println(s);
}
}
/*
输出:
Student@15db9742
*/
//自己提供构造方法
class Student{
//构造方法
public Student(){
System.out.println("自己写一个构造方法");
}
}
class ConstructDemo{
public static void main(String[] args){
//创建对象
Student s = new Student();
System.out.println(s);
}
}
/*
输出:
自己写一个构造方法
Student@15db9742
6.2 构造方法的格式
- 方法名与类名相同 (方法名与类名相同的方法不一定是构造方法)
- 没有返回值类型,连void都没有
- 没有具体的返回值(没有return)
6.3 构造方法的注意事项
- 如果你不提供构造方法,系统会给出默认无参构造方法
- 如果你提供了构造方法(无论是有参还是无参),系统将不再提供无参构造方法
- 构造方法也是可以重载的
案例8:构造方法的重载(重载:方法名相同参数列表——参数个数或参数类型——不同)
//自己提供构造方法
class Student{
//私有化成员变量
private String name;
private int age;
//无参构造方法
public Student(){
System.out.println("这是一个无参构造方法");
}
//写一个公共方法访问成员变量
public void show(){
System.out.println(name+":"+age);
}
//只有一个String类型参数的构造方法
public Student(String name){
System.out.println("这是一个带String类型的构造方法");
this.name = name;
}
//只有一个int类型参数的构造方法
public Student(int age){
System.out.println("这是一个带int类型的构造方法");
this.age = age;
}
//带String类型和int类型的构造方法
public Student(String name,int age){
System.out.println("这是一个带String和int类型的构造方法");
this.name = name;
this.age = age;
}
}
class ConstructDemo{
public static void main(String[] args){
//创建对象s并通过无参构造方法Student()赋默认值
Student s = new Student();
//通过对象访问无参构造方法从而输出成员变量
s.show();//输出的为默认值
System.out.println("-------");
//创建对象s1并通过String类型的参数构造方法为变量name赋值
Student s1 = new Student("卡卡西");
s1.show();//输出:卡卡西:0
System.out.println("-------");
//创建对象s2
Student s2 = new Student(7);
s2.show();
System.out.println("-------");
//创建对象s3
Student s3 = new Student("卡卡西",7);
s3.show();
System.out.println("-------");
}
}
构造方法的一个用途:给成员变量赋值
给成员变量赋值的两个方法:
- setXxx();
- 构造方法
小结:
- 类的组成——成员变量;构造方法;成员方法
- 对于成员变量:一般私有化
- 对于构造方法:a.作用;b.格式;c.注意事项;d.无参和有参
- 成员方法
成员方法的分类及使用:
成员方法——其实就是前面讲过的方法
成员方法的分类
根据返回值——1. 有明确返回值方法(必须由return返回一个值);2. 返回void类型的方法
根据形式参数——1. 无参方法;2. 带参方法
7. 一个基本类的标准代码写法
类的组成:
1.成员变量
一般私有化
2.构造方法
无参构造方法
带参构造方法
3.成员方法
getXxx()
setXxx()
其他功能的方法
给成员变量赋值的方式
无参构造方法+setXxx()
带参构造方法
案例9:一个标准的学生类
//一个标准代码的最终版
/*
学生类:
成员变量
name,age
构造方法
无参构造方法,带两个参的构造方法
成员方法
getXxx(),setXxx()
show()——输出该类的所有成员变量
*/
//学生基本类
class Student{
//定义成员变量
private String name;
private int age;
//无参构造方法
public Student(){}
//有两个参的构造方法
public Student(String name,int age){
this.name = name;
this.age = age;
}
//输出姓名的成员方法
public String getName(){
return name;
}
//赋值姓名的成员方法
public void setName(String name){
this.name = name;
}
//输出年龄的成员方法
public int getAge(){
return age;
}
//赋值年龄的成员方法
public void setAge(int age){
this.age = age;
}
//show()方法输出全部数据
public void show(){
System.out.println(name+":"+age);
}
}
//学生类的测试类
class StudentTest{
public static void main(String[] args){
//给成员变量赋值方式1:无参构造方法+setXxx()
//创建一个对象s
Student s = new Student();
//给成员对象赋值
s.setName("卡卡西");
s.setAge(7);
//show方法输出
s.show();
System.out.println("-----");
//给成员变量赋值方式2:有参构造方法
//创建一个对象S1
Student s1 = new Student("小丸子",5);
s1.show();
}
}
8. static关键字
8.1 static关键字的作用
可以修饰成员变量和成员方法
8.2 static关键字的特点
- 随着类的加载而加载
- 优先于对象存在
- 既可以通过对象名(对象名.变量名)调用,又可以用过类名调用(类名.变量名),一般推荐用类名调用
- 被类的所有对象共享
判断是否使用静态关键字的条件:如果某个成员变量是被所有对象所共享的,那么就应该将其定义为静态的
静态修饰的内容我们一般称其为:与类相关的,即类成员;非静态:与对象相关的
8.3 static关键字的注意事项
- 在静态方法中是没有this关键字的
解释:静态方法不能访问非静态变量。因为静态是随着类的加载而加载,而this是随着对象的创建而存在的。静态先于对象存在。
- 静态方法只能访问静态的成员变量和静态的成员方法
静态方法:
对于成员变量——只能访问静态成员变量;
对于成员方法——只能访问静态成员方法;
非静态方法:
对于成员变量——既能访问静态的也能访问非静态的;
对于成员方法——既能访问静态成员方法又能访问非静态成员方法。
8.4 静态变量和成员变量的区别:
所属不同
- 静态变量属于类,所以也称为为类变量
- 成员变量属于对象,所以也称为实例变量(对象变量)
内存中位置不同
- 静态变量存储于方法区的静态区
- 成员变量存储于堆内存
内存出现时间不同
- 静态变量随着类的加载而加载,随着类的消失而消失
- 成员变量随着对象的创建而存在,随着对象的消失而消失
调用不同
- 静态变量可以通过类名调用,也可以通过对象调用
- 成员变量只能通过对象名调用
8.5 main方法是静态的
main方法的格式讲解:
public:
公共的。访问权限是最大的,因为main方法是被jvm调用的,所以权限要够大。
static:
静态的,不需要创建对象,通过类名就可以访问,方便jvm的调用。
void:
没有返回值。因为返回值时返回到调用者的,main方法是被jvm调用,要返回值无意义。
main:
是一个常见的方法入口,几乎所有语言是以main作为入口。
String [] args:
名为args的字符串类型的没有元素的数组,早期是为了接收键盘录入数据的。
格式:java main方法所在类名 hello world java
hello 、world 、java是录入该字符串数组的三个元素
9. 帮助文档
9.1 帮助文档的制作
- 写一个工具类
- 加入文档注释
- 通过javadoc工具解析文档注释——运行命令格式:javadoc -d 目录 -author -version ArrayTool.java
9.2 帮助文档的使用
- 找到文档,打开文档
- 点击显示,找到索引,出现输入框
- 在输入框中输入要学习的类名
- 首先看包——java.lang包下的类不需要导入,其他的全部需要导入
- 然后简单看看类的解释和说明(主要看例子,注意版本)
- 看类的结构:成员变量——字段摘要;构造方法——构造方法摘要;成员方法——成员方法摘要
- 学习构造方法:A.有构造方法,就创建对象;B.没有构造方法,成员可能都是静态的
- 看成员方法:是否静态,如果静态可以直接用类名调用;返回值类型;看方法名;看参数列表
10. 代码块
10.1 概念
在Java中,使用{}括起来的代码被称为代码块
10.2 分类
根据其位置和声明的不同,可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程讲解)
局部代码块
在 方法中 出现;用于限定变量生命周期,及早释放,提高内存利用率
构造代码块
在 类中方法外 出现用{ }的代码;多个构造方法方法中相同的代码存放到一起,每次调用构造都执行,并且在构造方法前执行
静态代码块
在 类中方法外 出现,加了static修饰;用于给类进行初始化,在加载的时候就执行,并且只执行一次
静态代码块,构造代码块、构造方法的执行顺序:
静态代码块(只执行一次)→ 构造代码块(每次调用构造方法都执行)→ 构造方法