✨你好啊,我是“ 罗师傅”,是一名程序猿哦。
🌍主页链接:楚门的世界 - 一个热爱学习和运动的程序猿
☀️博文主更方向为:分享自己的快乐 briup-jp3-ing
❤️一个“不想让我曾没有做好的也成为你的遗憾”的博主。
💪很高兴与你相遇,一起加油!

前言

目标:Java基础编程,熟练Java开发语法和规则,养成良好编程习惯

本节理论较多,注意不要睡着了哈💦💦💦

面向对象

  • OOP(object oriented programming), 面向对象编程
    • 是一种以对象为中心的编程思想,通过借助对象实现具体的功能
    • 大问题拆分为小问题,然后借助不同对象分别解决,最终实现功能
  • POP(procedure oriented Programming),面向过程编程
    • 是一种以过程为中心的编程思想,靠自己一步一步去实现功能,需要对每个步骤精确控制
    • 强调按步骤实现功能,先分析解决问题锁需步骤,再定义方法实现每个步骤功能,然后依次调用方法,最终实现功能

面向对象语言特征

  • 封装(encapsulation)信息隐蔽
  • 继承(inheritance)代码重用
  • 多态(polymorphism)灵活、接口统一

Java语言、C++、Python等都是面向对象程序设计语言中的一种,所以都具有这三种特征

专业的人去做专业的事情 –> 合适的对象去调用合适的方法

面向对象的特点:

  • 更符合人类思想习惯的思想
  • 利用对象去实现功能
  • 可以将复杂事情简单化(针对要解决问题的用户而言)
  • 我们的角色由执行者变成了指挥者

对象理解

自然界中客观存在的事物皆为对象 ,万物皆对象

理解对象

  • 任何事物都是一个对象(object)
  • 对象由对象组成
  • 每个对象都有属性(静态的描述信息)行为(动态的功能描述)
  • 具有相似和行为的对象可以归为一类

类的定义

具有相同属性和行为的对象可以抽象为类(数据类型的一种)

类的组成:

  • 属性:指事物的特征,静态描述,例如:手机品牌,价格,尺寸
  • 行为:指事物所具有的功能,动态描述;例如:手机可以打电话,也可以发短信

类的理解:

  • 类是对现实生活中一类具有共同属性和行为的事物的抽象
  • 类是对象的数据类型,类是具有相同属性和行为的一组对象的集合
  • 简单理解:类就是对现实事物的一种描述
  • 类是引用数据类型中的一种

结论:类是对象的抽象,对象是类的实例

类定义的格式:

1
2
3
4
5
6
7
8
9
10
11
12
[public] class 类名 {
//属性,可以包含多个
[权限修饰符] 数据类型 成员变量名;
//行为,可以包含多个
[权限修饰符] 返回值类型 成员方法名(形参列表) {
具体功能实现
}
//构造器
[权限修饰符] 类名(形参列表) {
初始化语句
}
}

类定义步骤:

  • 定义类
  • 编写类的成员变量
  • 编写类的成员方法

对象使用

创建对象格式:

  • 类名 对象名 = new 类名();

调用成员格式:

  • 对象名.成员变量
  • 对象名.成员方法()
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Test04_Student {
public static void main(String[] args) {
Student stu = new Student();
System.out.println(stu.name); // null
System.out.println(stu.sid); // 0

stu.name = "lwsj";
stu.sid = 1001;
System.out.println(stu.name); // lwsj
System.out.println(stu.sid); // 1001

stu.sleep(100, "躺着");

// 全类名:包名.类名
// com.briup.chap05.pojo.Student@659e0bfd
System.out.println(stu);
}
}

类使用总结:

  • 一般Java程序会写两个类:基础类,测试类
  • 基础类就是我们要实现封装出来的那个类
  • 测试类就是包含main方法的类
  • 注意:只能在一个类中定义main方法,其是程序的入口,必须唯一

数据类型理解:

Java中对数据类型的描述和定义,都是抽象的,每一种数据类型,都是对一类数据抽象描述,描述这种数据的基本特点。

int、String和Student都是对数据的抽象描述,不能当做具体的数据使用,如果想使用的这些数据的话,如果想使用的这些数据的话,必须使用int或String类型定义变量,使用Student实例化对象,然后使用变量或对象来参与运算

类和对象的关系:

类是一组相关属性和行为的集合,它是对某一种具体事物的抽象描述。

也可以吧类看做一个模板,我们使用的对象,就是按照这个模板中的定义,来进行创建的。

  • 类是对一类事物的描述,是抽象的
  • 对象是一类事物的实例,是具体的
  • 类是对象的模板,对象是类的实体

结论:类是一种抽象的数据描述,对象是类的一个具体的实例。

对象内存

1
2
3
4
5
6
7
8
public static void main(String[] args) {
// 实例化对象
Student stu = new Student();
stu.name = "tom";
stu.age = 20;

stu.sayHello();
}
  • 单个对象内存图
  • 程序运行过程:
    • 加载Student类:把Student.class文件内容加载到方法区
    • 加载main方法并运行:整个main方法的代码都被加载到栈区
    • 创建引用类型变量:在栈空间中开辟一块内存空间,用stu标识
    • 在堆中开辟内存创建对象,并给属性赋上默认初始值
    • 将堆空间对象内存地址值放入stu标识的内存区域中
    • 对象属性赋值:将“tom”和20放入堆空间对象内存区域内
    • 对象方法调用:找到方法区sayHello方法对应的代码,执行
    • main方法继续执行,遇到 } ,程序执行结束

引用类型理解:上述案例中,stu是一个引用类型变量,其对应栈区的一块内存区域,其中放的是一个引用值(地址值),通过这个引用值,系统可以找到对象实际开辟的内存空间(堆区),进而进行对象属性操作或方法调用。

  • 多个对象
1
2
3
4
5
6
7
8
9
10
11
>public static void main(String[] args) {
Student s1 = new Student();
s1.name = "lucy";

Student s2 = new Student();
s2.name = "jack";
s2.age = 20;

s1.sayHello();
s2.study(100, "flay");
>}

对象内存结论:

  • 系统会为每个对象开辟单独的内存空间(堆空间),用来存储对象的属性
  • 类的成员方法存储在方法区,只保留一份,只要是该类的对象,都可以调用。

变量对比

到目前为止,我们学习了两种变量:成员变量、局部变量。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class Test06_Variate {
int num; // 成员变量

public void setNum(int newNum) {
num = newNum; // newNum 局部变量
}

public static void main(String[] args) { // args 局部变量
Scanner sc = new Scanner(System.in); // sc 局部变量
System.out.println("input a num: ");
int number = sc.nextInt(); // 局部变量

Test06_Variate t = new Test06_Variate(); // 局部变量
t.setNum(number);

System.out.println(t.num);
}
}

成员、局部变量区别:

  • 定义位置不同
    • 成员变量:在类中,方法外
    • 局部变量:方法内部或方法声明上(形参列表)
  • 内存中位置不同
    • 成员变量:堆内存
    • 局部变量:栈内存(方法内)
  • 生命周期不同
    • 成员变量:随着对象的存在而存在,随着对象的消失而消失
    • 局部变量:随着方法的调用而存在,随着方法的调用完毕而消失
  • 初始化值不同
    • 成员变量:有默认初始值
    • 局部变量:没有默认初始值,必须先定义,赋值才能使用

封装特性

概念理解

封装是面向对象三大特征之一,另外两个是继承,多态

封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。

其优点如下:

  • 通过方法来控制成员变量的操作提高了代码的安全性
  • 代码用方法进行封装提高了代码的复用性
  • 隐藏代码实现细节,提供公共访问方式简化操作

例子:

我觉得最能体先 封装 的例子就是 适配器模式

比如我们有两种充电器,一个三角三口的,一个是两个直口的

我们现在只有一个泰国牌子的 插座 ,就是两个孔的

这个时候我们就可以通过一个转换器 两孔口 —> (一个三口+两个直口的)

这个时候对于两边(用户和提供方)来说都不需要知道转换器具体的内部细节,只需要知道适配器提供了怎么样的接口

封装原则:

  • 把不需要对发提供的内容隐藏起来
  • 把属性隐藏,提供公共方法对其访问

private

private、public都是权限修饰符,可以用来修饰成员变量、成员方法和构造方法;

  • private(私有),用它修饰类的成员(含成员变量、成员方法),则这些成员只能在类内(类的成员函数内部)去使用,其他地方不可以操作;
  • public表示公有,用它修饰类的成员(含成员变量、成员方法),则这些成员在类内、类外都可以操作

封装实现

  • 使用private修饰成员变量
  • 提供对应setXxx()、getXxx()方法,用public修饰
  • 具体使用时,借助对象的setXxx方法给属性赋值,getXxx方法获取属性值
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
package com.briup.chap05.pojo;

/**
* 账户类 封装版
*
* public 所有位置
*
* protected
*
* (不写)
*
* private (最小,只能在类中使用)
*
* @author luozongwei
*
*/
public class Account {
private String id;
private double balance;

public void setId(String id) {
this.id = id;
}

public String getId() {
return id;
}

public double getBalance() {
return balance;
}

public void setBalance(double balance) {
this.balance = balance;
}
}
public class Test2_AccountTest {
public static void main(String[] args) {
Account account = new Account();
System.out.println(account.getId());
System.out.println(account.getBalance());
}
}

this关键字

在类中的普通成员方法中,可以使用this关键字,其表示调用当前方法的对象引用,即哪个对象调用该方法,this就代表哪一个对象。

this关键字用法:

  • 对成员变量和局部变量进行区分:this.数据成员
  • 调用类中的成员方法:this.成员方法(实际参数列表)
  • 调用类中的其他构造器:this.构造函数(实参)

成员变量与局部变量的区分:

  • 方法的形参如果与成员变量同名
    • 不带this修饰的变量指的是形参
    • 如果要表示成员变量,则必须加this修饰
  • 方法的形参与成员变量不同名
    • 则不带this修饰的变量指的就是成员变量
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
private String id;
private double balance;

public void setId(String id) {
this.id = id;
}
public void setBalance(double balance) {
this.balance = balance;
}
// 构造方法
public Account(String id, double balance) {
this.id = id;
this.balance = balance;
}
public Account(String id) {
// 使用this关键字在构造器里调用其他的重载构造器
// 一般是少的调用多的
this(id, 100.0);
}

this内存构成理解

1
2
3
4
5
6
public static void main(String[] args) {
Student stu1 = new Student("zs",21);
stu1.sayHello();
Student stu2 = new Student("tom",19);
stu2.sayHello();
}
  • 单个对象内存图
  • 多个对象内存图

观察上图可知:每一个对象中,都有自己的this,和其他对象中的互不影响。

  • 当前执行stu1.sayHello()代码的时候,this代表的就是stu1

  • 当前执行stu2.sayHello()代码的时候,this代表的就是stu2

结论:成员方法被哪个对象调用,方法中的this就代表那个对象。即谁调用,this就代表谁。

构造方法

构造方法可以对对象进行初始化操作,即为对象开辟内存空间的时候,给对象的成员成员赋初值

构造方法格式:

1
2
3
[修饰符] 类名(参数列表) {
初始化语句s;
}

注意事项:

  • 构造方法一般使用public修饰
  • 构造方法没有返回值类型,连void都没有
  • 构造方法名和类名相同(区分大小写)
  • 构造方法可以重载
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
package com.briup.chap05.pojo;

public class Teacher {
private String name;
private double salary;

// 无参构造
public Teacher() {
System.out.println("Teacher()...");
}

public Teacher(String name, double salary) {
System.out.println("Teacher(String, double)...");
this.name = name;
this.salary = salary;
}

public void show() {
System.out.println("name: " + name);
System.out.println("salary:" + salary);
}
}

执行时机:

  • 创建对象的时候调用,每创建一次对象,就会执行一次构造方法
  • 不能手动调用构造方法
1
2
3
4
5
6
7
8
9
public static void main(String[] args) {
Teacher t1 = new Teacher();
t1.show();
System.out.println("--------------------------");
Teacher t2 = new Teacher("kevin", 13099.5);
t2.show();
// 手动调用构造方法,错误用法,无法通过编译
// t2.Teacher();
}

创建对象时构造器会被自动调用实例化对象时指定的那 个构造方法),其完成了对象属性的初始化。

注意事项补充:

  • 用户不定义构造方法,系统会提供一个无参构造方法
1
2
3
public 类名(){
// nothing to do
}
  • 用户定义构造方法,系统则不再提供无参构造方法
  • 用户不需要也不可以主动调用构造方法,系统会自动调用

对象创建步骤:

1
2
3
public static void main(String[] args) {
Student stu = new Student("zhang", 23);
}
  • 将Student.class文件加载到内存方法区
  • 在main栈帧开辟一块内存,用stu标识
  • 在堆中开辟内存创建对象
  • 给属性以默认初始值(null,0)
  • 属性进行显式初始化(如果存在的话,比如private int age = 10;)
  • 调用构造方法,用(“zhang”, 23)给属性赋值
  • 将堆中对象的内存地址赋值给stu,对象创建完成

this补充

this特殊用法:

在构造方法中,可以借助this关键字调用其他构造方法

具体格式为: this(实际参数列表);

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
public class Teacher {
//...省略
//该类已经成功定义2参构造器,定义过程省略
//public Teacher(String name, double salary);
//this特殊用法:在构造方法中,调用其他构造方法
public Teacher(String name) {
//必须是构造方法的第一行有效代码
this(name,0);
}
}

public class Test10_This {
public static void main(String[] args) {
//调用Teacher(String)构造方法实例化对象
//底层借助Teacher(String, double)实现
Teacher t = new Teacher("larry");
t.show(); //
}
}
// Teacher(String, double)...
// name: lucy
// salary:0.0

构造方法Teacher(String)底层借助Teacher(String, double)实现了 功能。

注意: this(实际参数列表) 必须是构造方法中的第一行有效代码。

❤️❤️❤️忙碌的敲代码也不要忘了浪漫鸭!

盛年不再来,一日难再晨,及时当勉励,岁月不待人。—- 陶渊明💪