0%

Java(4)面向对象

JAVA面向对象

  • 面向过程:当需要实现一个功能的时候,每一个具体的步骤都要亲力亲为,详细处理每一个细节。

  • 面向对象:当需要实现一个功能的时候,不关心具体的步骤,而是找一个已经具有该功能的人,来帮我做事。

生活中的例子:

  • 面向过程:把衣服脱下来 —>找一个盆—>放点洗衣粉—>加点水—>浸泡10分钟—>揉一揉—>清洗衣服—>拧干—>晾起来
  • 面向对象:把衣服脱下来 —>打开全自动洗衣机—>扔衣服—>按钮—>晾起来

区别:

  • 面向过程:强调步骤。
  • 面向对象:强调对象,这里的对象就是洗衣机。

特点:

  • 面向对象思想是一种更符合我们思考习惯的思想,它可以将复杂的事情简单化,并将我们从执行者变成了指挥者。面向对象的语言中,包含了三大基本特征,即封装、继承和多态

程序中的面向对象:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package com.tipdm.demo2;

import java.util.Arrays;

public class demo1 {
public static void main(String[] args) {
int[] array = {10, 20, 30, 40, 50};
// 要求打印格式为:[10, 20, 30, 40, 50]
// 使用面向过程
System.out.print("[");
for (int i = 0; i < array.length-1; i++) {
System.out.print(array[i]);
System.out.print(", ");
}
System.out.println(array[array.length-1] + "]");
System.out.println("=======================");
// 使用面向对象
// 找一个JDK给我们提供好的Arrarys类
/// 其中有一个toString方法,直接就能把数组变成想要的格式的字符串
System.out.println(Arrays.toString(array));
}
}

1
2
3
4
5
[10, 20, 30, 40, 50]
=======================
[10, 20, 30, 40, 50]

进程已结束,退出代码0

类和对象

什么是类?

:是一组相关属性和行为的集合。可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该类事物。

现实中,描述一类事物:

  • 属性 :就是该事物的状态信息。
  • 行为 :就是该事物能够做什么。

举例:小猫。

  • 属性:名字、体重、年龄、颜色。
  • 行为:走、跑、叫。

什么是对象?

对象 :是一类事物的具体体现。对象是类的一个实例,必然具备该类事物的属性和行为。

现实中,一类事物的一个实例:一只小猫。

举例:一只小猫。

  • 属性:tom、5kg、2 years、yellow。
  • 行为:溜墙根走、蹦跶的跑、喵喵叫。

类与对象的关系

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

image-20211207140229556

类的定义

事物与类的对比

现实世界的一类事物:

  • 属性:事物的状态信息。
  • 行为:事物能够做什么。

Java中用class描述事物也是如此:

  • 成员变量:对应事物的属性
  • 成员方法:对应事物的行为

类的定义格式

1
2
3
4
public class ClassName{
// 成员变量
// 成员方法
}
  • 定义类 :就是定义类的成员,包括成员变量成员方法
  • 成员变量 :和以前定义变量几乎是一样的。只不过位置发生了改变。在类中,方法外
  • 成员方法 :和以前定义方法几乎是一样的。只不过static去掉static的作用在面向对象后面再详细讲解。

类的定义格式举例:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
public class Student {
// 成员变量
String name; // 姓名
int age; // 年龄

// 成员方法
public void eat(){
System.out.println("吃饭!");
}
public void sleep(){
System.out.println("睡觉!");
}
public void study(){
System.out.println("学习!");
}
}

调用:

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
44
45
46
47
48
49
50
package com.tipdm.demo2;

/**
* 通常情况下,一个类并不能直接使用,需要根据类创建一个对象,才能使用。
*
* 1. 导包
* import 包名称.类名称;
* import com.tipdm.demp2.Student;
* 对于和当前类术语同一个包的情况,可以省略导包语句不写。
* 2. 创建
* 格式:类名称 对象名 = new 类名称();
* Student stu = new Student();
* 3. 使用
* 使用成员变量:对象名.成员变量名
* 使用成员方法:对象名.成员方法名()
*
* 注意事项:
* 如果成员变量没有进行赋值,那么将会有一个默认值,规则和数组一样
*/

public class demo2 {
public static void main(String[] args) {
// 1. 导包。
// 我需要使用的Student类,和我自己demo2位于同一个目录下,所以可以省略不写

// 2. 创建
Student stu = new Student();

// 3. 使用
System.out.println(stu.age); // 由于没有写,所以输出的是默认值
System.out.println(stu.name);

// 改变对象当中的成员变量数值内容
// 将右侧的字符串,赋值给stu对象当中的name成员变量
System.out.println("=========");
stu.age = 20;
stu.name = "赵丽颖";
System.out.println(stu.age); // 改变了默认值
System.out.println(stu.name);

// 4. 使用对象的成员方法
System.out.println("=========");
stu.eat();
System.out.println("=========");
stu.sleep();
System.out.println("=========");
stu.study();
}
}

1
2
3
4
5
6
7
8
9
10
11
12
13
0
null
=========
20
赵丽颖
=========
吃饭!
=========
睡觉!
=========
学习!

进程已结束,退出代码0

image-20211207142538994

类与对象的练习

定义一个类,用来模拟“手机”事物。

  • 属性:品牌,价格,颜色
  • 行为:打电话,发短信

对应到类当中:

成员变量(属性):

  • String brand;
  • double price;
  • String color;

成员方法(行为):

  • public void call(String who){} // 打电话
  • public void sendMessage(){} // 群发短信
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
package com.tipdm.demo2;

public class Phone {
String brand;
double price;
String color;

public void call(String who){
System.out.println("Call:" + who);
}

public void sendMessage(){
System.out.println("Hello\nFrom:" + brand);
}
}

调用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.tipdm.demo2;

public class demo3 {
public static void main(String[] args) {
Phone phone1 = new Phone();

System.out.println(phone1.brand);
System.out.println(phone1.color);
System.out.println(phone1.price);

phone1.brand = "华为P30 Pro";
phone1.color = "黑色";
phone1.price = 2999.0;

System.out.println("=========");
System.out.println(phone1.brand);
System.out.println(phone1.color);
System.out.println(phone1.price);

phone1.call("Luo Ming");
phone1.sendMessage();
}
}

1
2
3
4
5
6
7
8
9
10
11
12
null
null
0.0
=========
华为P30 Pro
黑色
2999.0
Call:Luo Ming
Hello
From:华为P30 Pro

进程已结束,退出代码0

对象调用的内存图

单个对象

image-20211207145559150

两个对象,不产生交叉

image-20211207151113003

两个对象,产生交叉

image-20211207151038099

使用对象类型作为方法的参数image-20211207152033793

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.tipdm.demo2;

public class demo4 {
public static void main(String[] args) {
Phone phone1 = new Phone();

phone1.brand = "华为";
phone1.color = "黑色";
phone1.price = 2999.0;

method(phone1);
}

public static void method(Phone p){
System.out.println(p.brand);
System.out.println(p.color);
System.out.println(p.price);
}
}

1
2
3
4
5
华为
黑色
2999.0

进程已结束,退出代码0

使用对象类型作为方法的返回值

image-20211207152939842

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
package com.tipdm.demo2;

public class demo5 {
public static void main(String[] args) {
Phone one = getPhone();
one.brand = "苹果";
System.out.println(one.brand);
System.out.println("=============");
Phone two = getPhone();
System.out.println(two.brand);
}

public static Phone getPhone(){
Phone phone = new Phone();
phone.brand = "华为";
phone.color = "黑色";
phone.price = 2999.0;
return phone;
}
}
1
2
3
4
5
苹果
=============
华为

进程已结束,退出代码0

局部变量和成员变量不同点

1.定义的位置不一样【重点】

局部变量:在方法的内部

成员变量:在方法的外部

2.作用范围不一样【重点】

局部变量:只有在方法当中才可以使用,出了方法就不能再用

成员变量:整个类全都可以通用

3.默认值不一样【重点】

局部变量:没有默认值,如果要想使用,必须手动进行赋值

成员变量:如果没有赋值,会有默认值,规则和数组一样

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
package com.tipdm.demo2;

public class demo6 {
String name; // 成员变量

public void methodA(){
int num = 20; // 局部变量
System.out.println(num);
System.out.println(name); // 成员变量有默认值,就算没有赋值也可以使用,规则和数组一样。
}

public void methodB(){
// System.out.println(num); // 错误写法,局部变量无法在其他的方法中使用
System.out.println(name); // 正确写法,成员变量在整个方法中都可以使用
// int a;
// System.out.println(a); // 局部变量无默认值,没赋值不能使用
}
}

4.内存的位置不一样(了解)

局部变量:位于栈内存

成员变量:位于堆内存

5.生命周期不一样(了解)

局部变量:随着方法进栈而诞生,随着方法出栈而消失。

成员变量:随着对象创建而诞生,随着对象被垃圾回收而消失。

面向对象的三大特性之封装性

面向对象编程语言是对客观世界的模拟,客观世界里成员变量都是隐藏在对象内部的,外界无法直接操作和修改。封装可以被认为是一个保护屏障,防止该类的代码和数据被其他类随意访问。要访问该类的数据,必须通过指定的方式。适当的封装可以让代码更容易理解与维护,也加强了代码的安全性。

属性隐藏起来,若需要访问某个属性,提供公共方法对其访问。

封装的步骤

  1. 使用 private 关键字来修饰成员变量。

  2. 对需要访问的成员变量,提供对应的一对 getXxx 方法 、 setXxx 方法。

private关键字和this关键字

private的含义

  1. private是一个权限修饰符,代表最小权限。
  2. 可以修饰成员变量和成员方法。
  3. 被private修饰后的成员变量和成员方法,只在本类中才能访问。

this的含义

  • this代表所在类的当前对象的引用(地址值),即对象自己的引用,类似与Python中的self。

private的使用格式

1
private 数据类型 变量名;
  1. 使用private修饰成员变量,代码如下:
1
2
3
private String name;
private int age;
private boolean male;
  1. 设置Gatter/Setter方法

public void setName(String name) {
this.name = name;
}

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
public String getName() {
return name;
}

public void setAge(int age) {
if (age >= 0 && age < 200){
this.age = age;
} else{
System.out.println("年龄错误!");
}
}

public int getAge() {
return age;
}

public void show(){
System.out.println("我叫:" + name + ", 年龄:" + age + ",男性:" + male);
}

public boolean isMale() {
return male;
}

public void setMale(boolean male) {
this.male = male;
}

调用:

1
2
3
4
5
6
7
8
9
10
11
package com.tipdm.demo3;

public class demo1 {
public static void main(String[] args) {
Student stu = new Student();
stu.setName("赵丽颖");
stu.setAge(20);
stu.setMale(false);
stu.show();
}
}

结果:

1
2
3
我叫:赵丽颖, 年龄:20,男性:false

进程已结束,退出代码0

构造方法

当一个对象被创建时候,构造方法用来初始化该对象,给对象的成员变量赋初始值。

小贴士:无论你与否自定义构造方法,所有的类都有构造方法,因为Java自动提供了一个无参数构造方法,一旦自己定义了构造方法,Java自动提供的默认无参数构造方法就会失效。

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
44
45
46
47
48
49
50
51
52
package com.tipdm.demo3;

/**
* 构造方法是专门用来创建对象的方法,当我们通过关键字new来创建对象时,其实就是再调用构造方法。
* 格式:
* public 类名称(参数类型 参数名称){
* 方法体
* }
*
* 注意事项:
* 1. 构造方法的名称必须和所在的类名称完全一样,就连大小写也要一样
* 2. 构造方法不要写返回值类型,连void都不写
* 3. 构造方法不能return一个具体的返回值
* 4. 如果没有编写任何构造方法,那么编译器将会默认赠送一个构造方法,没有参数,方法体什么事情也不做。public Student(){}
* 5. 一旦编写了至少一个构造方法,那么编译器将不再赠送。
* 6. 构造方法也是可以进行重载的
*/
public class Person {
// 成员构造
private String name;
private int age;

// 全参数构造方法
public Person(String name, int age){
System.out.println("全参构造方法执行了!");
this.name = name;
this.age = age;
}

// 无参数构造方法
public Person() {
System.out.println("无参构造方法执行了!");
}

// Getter Setter
public void setName(String name) {
this.name = name;
}

public String getName() {
return name;
}

public int getAge() {
return age;
}

public void setAge(int age) {
this.age = age;
}
}

调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.tipdm.demo3;

public class demo2 {
public static void main(String[] args) {
Person person1 = new Person(); // 无参构造
Person person2 = new Person("赵丽颖", 18); // 全参构造
System.out.println(person1.getName());
System.out.println(person2.getName());
// 如果需要改变对象当中的成员变量数据内容,仍然还需要使用setXxx方法
person2.setAge(21); // 改变年龄
System.out.println(person2.getAge());
}
}

结果:

1
2
3
4
5
6
7
无参构造方法执行了!
全参构造方法执行了!
null
赵丽颖
21

进程已结束,退出代码0

构造一个标准类

一个标准的类通常要拥有下面四个组成部分:

  1. 所有的成员变量都要使用private关键字修饰
  2. 为每一个成员变量编写一对Getter/Setter方法
  3. 编写一个无参数的构造方法
  4. 编写一个全参数的构造方法
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
package com.tipdm.demo4;

/**
* 一个标准的类通常要拥有下面四个组成部分:
* 1. 所有的成员变量都要使用private关键字修饰
* 2. 为每一个成员变量编写一对Getter/Setter方法
* 3. 编写一个无参数的构造方法
* 4. 编写一个全参数的构造方法
*
* 标准的类也叫做Java Bean
*/
public 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;
}
}

调用:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package com.tipdm.demo4;

public class Demo01Student {
public static void main(String[] args) {
Student stu1 = new Student();
stu1.setName("赵丽颖");
stu1.setAge(18);
System.out.println("姓名:" + stu1.getName() + ", 年龄:" + stu1.getAge());
System.out.println("=======================");
Student stu2 = new Student("迪丽热巴", 20);
System.out.println("姓名:" + stu2.getName() + ", 年龄:" + stu2.getAge());
stu2.setAge(18);
System.out.println("姓名:" + stu2.getName() + ", 年龄:" + stu2.getAge());
}
}
1
2
3
4
5
6
姓名:赵丽颖, 年龄:18
=======================
姓名:迪丽热巴, 年龄:20
姓名:迪丽热巴, 年龄:18

进程已结束,退出代码0
-------------本文结束感谢您的阅读-------------