• 面向对象是啥?

    • 面向:找、拿。
    • 对象:东西。
    • 面向对象编程:找或拿东西过来编程。
  • 面向对象编程的好处:符合人类思维习惯,编程更简单,更好理解

  • 面向对象学习什么?学习自己设计对象并使用,面向对象的语法

设计对象并使用

设计类,创建对象并使用

  • 类是什么?

    • 类(设计图) :是对象共同特征的描述;
    • 对象:是真实存在的具体实例。
    • 结论:在Java中,必须先设计类,才能创建对象并使用。
  • 如何设计类

    1
    2
    3
    4
    5
    6
    7
    public class 类名 {
    1、成员变量(代表属性,一般是名词)
    2、成员方法(代表行为,一般是动词)
    3、构造器 (后几节再说)
    4、代码块 (后面再学)
    5、内部类 (后面再学)
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class Car {
    // 属性 (成员变量)
    String name;
    double price;
    // 行为(方法)
    public void start(){

    }
    public void run(){

    }
    }
  • 如何得到类的对象

    1
    2
    类名 对象名 = new 类名();
    Car c = new Car();
  • 如何使用对象

    1
    2
    访问属性: 对象名.成员变量
    访问行为: 对象名.方法名(…)
  • 类和对象是什么?

    • 类:是共同特征的描述(设计图);对象:是真实存在的具体实例。
  • 如何设计类?

    1
    2
    3
    4
    public class 类名 {
    1、成员变量(代表属性的,一般是名词)
    2、成员方法(代表行为的,一般是动词)
    }
  • 如何创建对象?

    1
    类名 对象名 = new 类名();
  • 拿到对象后怎么访问对象的信息?

    1. 对象.成员变量;
    2. 对象.成员方法(…)

设计类:

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
package study;

// 定义类,用public修饰的类名必须成为java代码文件名
public class Friend {
// 成员变量 (属性)
String name;
int age;
double height;

// 成员方法(行为)
public void study(){
System.out.println("与你一起学习");
}
public void eat(){
System.out.println("等你一起吃饭");
}
}

// 定义Java文件的第二个类,但不能再使用public修饰
class BoyFriend {
// 成员变量 (属性)
String name;
int age;
double height;

// 成员方法(行为)
public void play(){
System.out.println("陪你一起打游戏");
}
public void relax(){
System.out.println("约你一起看电影");
}
}

创建对象:

1

定义类的几个补充注意事项

  • 类名首字母建议大写,且有意义,满足“驼峰模式”。
  • 一个Java文件中可以定义多个class类,但只能一个类是public修饰,而且public修饰的类名必须成为代码文件名。(实际开发中建议还是一个文件定义一个class类
  • 成员变量的完整定义格式是:修饰符 数据类型 变量名称 = 初始化值; 一般无需指定初始化值,存在默认值。
数据类型 明细 默认值
基本类型 byte、short、char、int、long 0
float、double 0.0
boolean false
引用类型 类、接口、数组、String null

封装

封装思想概述

  • 面向对象的三大特征:封装,继承,多态
  • 封装:告诉我们,如何正确设计对象的属性和方法。
  • 封装的原则:对象代表什么,就得封装对应的数据,并提供数据对应的行为
  • 理解封装思想有啥好处?
    • 有什么事,找对象,调方法就行,编程变得很简单。
    • 降低我们的学习成本,可以少学、少记。
  • 什么是封装啊?
    • 告诉我们,如何正确设计对象的属性和方法。
    • 原则:对象代表什么,就得封装对应的数据,并提供数据对应的行为。
  • 理解封装思想有什么好处?
    • 让编程变得很简单,有什么事,找对象,调方法就行。
    • 降低我们的学习成本,可以少学、少记,或者说压根不用学,不用记对象的那么多方法,有需要时去找就行。

如何更好的封装

  • 一般建议对成员变量使用private(私有、隐藏)关键字修饰进(private修饰的成员只能在当前类中访问
  • 为每个成员变量提供配套public修饰的的gettersetter方法暴露其取值和赋值
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
package study;

// 类
public class Student {
// 成员变量
private String name;
private int age;

// 成员方法
// 给成员变量生成 get set 方法
public void setName(String name){
this.name = name;
}

public String getName() {
return this.name;
}

public void setAge(int age){
if (age >= 0 && age <= 120) {
this.name = name;
} else {
System.out.println("年龄非法");
}
}

public int getAge() {
return this.age;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
package study;

public class StudentTest {
public static void main(String[] args) {
// 创建对象
Student student = new Student();
// 赋值
student.setAge(20);
// 取值
System.out.println(student.getAge());
}
}
  • 如何进行更好的封装?
    • 一般会把成员变量使用private隐藏起来,对外就不能直接访问了。
    • 提供public修饰的setter和getter方法暴露其赋值和取值。

this关键字

  • this关键字是什么

    • 可以出现在构造器、方法中
    • 代表当前对象的地址
      1
      2
      3
      4
      5
      6
      7
      8
      public class Car {
      public Car() {
      System.out.println("this在构造器中:" + this);
      }
      public void run() {
      System.out.println("this在方法中:" + this);
      }
      }
      1
      2
      3
      4
      5
      6
      7
      public class Test2{
      public static void main(String[] args) {
      Car c = new Car();
      c.run();
      System.out.println(c);
      }
      }
  • this关键字的作用:可以用于指定访问当前对象的成员变量、成员方法。

  • this出现在有参数构造器中的用法

    1
    2
    3
    4
    5
    6
    7
    8
    public class Car {
    String name;
    ouble price;
    public Car(String name , double price){
    this.name = name;
    this.price = price;
    }
    }
  • this出现在成员方法中的用法

    1
    2
    3
    4
    5
    6
    7
    public class Car {
    String name;
    double price;
    public void goWith(String name){
    System.out.println(this.name + "正在和" + name + "一起比赛!!");
    }
    }

    this用在成员方法中,谁去调用这个成员方法,this就代表谁
    this.可以省略

  • this关键字是什么?
    出现在构造器和成员方法中,代表当前对象的地址。

  • this关键字在构造器中、成员方法中可以做什么?
    可以用于指定访问当前对象的成员。


构造器

  • 学构造器的目的?

    1. 真正知道对象具体是通过调用什么代码得到的
    2. 能够掌握为对象赋值的其他简便写法
    3. 为以后学习面向对象编程的其他内容做支撑
  • 构造器的作用:定义在类中的,可以用于初始化一个类的对象,并返回对象的地址Car c = new Car();

  • 构造器的格式

    1
    2
    3
    修饰符 类名(形参列表){
    ...
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    public class Car {
    ...
    // 无参数构造器
    public Car(){
    ...
    }
    // 有参数构造器
    public Car(String n, double p){
    ...
    }
    }
  • 调用构造器得到对象的格式

    • 类 变量名称 = new 构造器;
    • Car c = new Car();
    • Car c1 = new Car("奔驰", 39.8);
  • 构造器的分类和作用

    • 无参数构造器(默认存在的):初始化对象时,成员变量的数据均采用默认值。
    • 有参数构造器:在初始化对象的时候,同时可以接收参数为对象进行赋值。
  • 构造器的注意事项

    • 任何类定义出来,默认就自带了无参数构造器,写不写都有。
      1
      2
      3
      4
      public class Car {
      ...
      // 无参数构造器(默认存在的)
      }
    • 一旦定义了有参数构造器,那么无参数构造器就没有了,如果还想用无参数构造器,此时就需要自己手写一个无参数构造器了。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      public class Car {
      ...
      // 无参数构造器(需要写出来了)
      public Car(){

      }
      // 有参数构造器
      public Car(String n, String b){

      }
      }
  • 构造器的作用?

    • 初始化类的对象,并返回对象的地址。
  • 构造器有几种,各自的作用是什么?

    • 无参数构造器:初始化对象时,成员变量的数据均采用默认值。
    • 有参数构造器:在初始化对象的时候,同时可以接收参数为对象进行赋值。
  • 构造器有哪些注意事项?

    • 任何类定义出来,默认就自带了无参数构造器,写不写都有。
    • 一旦定义了有参数构造器,无参数构造器就没有了,此时就需要自己写无参数构造器了。
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 study;

public class Car {

private String name;

private double price;

// 无参构造
public Car() {
System.out.println("无参构造执行了" + this);
}

// 有参构造
public Car(String name, double price) {
System.out.println("有参构造执行了");
this.name = name;
this.price = price;
}

public void run() {
System.out.println("this在方法中:" + this);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
package study;

public class CarTest {
public static void main(String[] args) {

// 无参构造,创建对象
Car car = new Car();
car.run();
System.out.println(car);

// 有参构造创建对象
// Car car2 = new Car("宝马", 43.15);
// Car car3 = new Car("奥迪rs7", 222.2);
}
}

无参构造执行了study.Car@1b6d3586
this在方法中:study.Car@1b6d3586
study.Car@1b6d3586


标准 JavaBean

  • JavaBean:也可以称为实体类,其对象可以用于在程序中封装数据。

  • 标准JavaBean须满足如下书写要求:

    • 成员变量使用 private 修饰。
    • 提供成员变量对应的 setXxx() / getXxx() 方法。
    • 必须提供一个无参构造器有参数构造器是可写可不写的。

按住快捷键Alt + Insert,选择Constructor/Getter/Setter,可以按住Ctrl键同时选择多个成员变量,可以快捷生成有参构造、变量取值方法、变量赋值方法。

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
package study;

/**
* 快捷键 Alt + insert 生成 Getter/Setter
*/
public class Person {
private double height;
private String location;
private String education;
private double income;
private String account;
private String phone;
private String password;

public Person() {
System.out.println("这是一个无参构造");
}

public Person(double height, String location, String education, double income, String account, String phone, String password){
System.out.println("这是一个有参构造");
this.height = height;
this.location = location;
this.education = education;
this.income = income;
this.account = account;
this.phone = phone;
this.password = password;
}

public double getHeight() {
return height;
}

public void setHeight(double height) {
this.height = height;
}
}

对象内存图

多个对象的内存图

2022-110 (1)

  • 对象到底是放在哪个位置的?
    堆内存中

  • Car c = new Car(); c变量名中存储的是什么?
    存储的是对象在堆内存中的地址。

  • 成员变量(name、price)的数据放在哪里,存在于哪个位置?
    对象中,存在于堆内存中。

两个变量指向同一个对象内存图

2022-110 (2)

  • 垃圾回收
    注意:当堆内存中的对象,没有被任何变量引用(指向)时,就会被判定为内存中的“垃圾”。

2022-110 (3)


补充知识:成员变量和局部变量区别

区别 成员变量 局部变量
类中位置不同 类中,方法外 常见于方法中
初始化值不同 有默认值,无需初始化 没有默认值,使用之前需要完成赋值
内存位置不同 堆内存 栈内存
生命周期不同 随着对象的创建而存在,随着对象的消失而消失 随着方法的调用而存在,随着方法的运行结束而消失
作用域 在归属的大括号中

面向对象综合案例

  • 案例:面向对象综合案例-模仿电影信息展示

    2022-110 (4)

  • 需求
    使用面向对象编程,模仿电影信息的展示。
  • 分析
    • 一部电影是一个Java对象,需要先设计电影类,再创建电影对象。
    • 三部电影对象可以采用数组存储起来。
    • 依次遍历数组中的每个电影对象,取出其信息进行展示。

      2022-110 (5)

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
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
package study;

public class Movie {
// 成员变量 (属性)
private String name;
private double score;
private String area;
private String type;
private String director;
private String actor;

// 无参数构造器
public Movie(){
}
// 有参数构造器
public Movie(String name, double score, String area, String type, String director, String actor) {
this.name = name;
this.score = score;
this.area = area;
this.type = type;
this.director = director;
this.actor = actor;
}

// 成员方法(行为)
// Getter / Setter
public String getName() {
return name;
}

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

public double getScore() {
return score;
}

public void setScore(double score) {
this.score = score;
}

public String getArea() {
return area;
}

public void setArea(String area) {
this.area = area;
}

public String getType() {
return type;
}

public void setType(String type) {
this.type = type;
}

public String getDirector() {
return director;
}

public void setDirector(String director) {
this.director = director;
}

public String getActor() {
return actor;
}

public void setActor(String actor) {
this.actor = actor;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
package study;

public class MovieTest {
public static void main(String[] args) {
// 创建movie类的数组
Movie[] movies = new Movie[3];

// 1.录入电影
movies[0] = new Movie("《隐入尘烟》", 8.5, "中国大陆", "剧情", "李睿珺", "武仁林/海清/杨光锐/武赟志/李生甫");
movies[1] = new Movie("《霸王别姬》", 9.6, "中国大陆/中国香港", "剧情/爱情", "陈凯歌", "张国荣/张丰毅/巩俐/葛优/英达");
movies[2] = new Movie("《千与千寻》", 9.4, "日本", "剧情/动画/奇幻", "宫崎骏", "柊瑠美/入野自由/夏木真理/菅原文太/中村彰男");

for (int i = 0; i < movies.length; i++) {
System.out.println("--------------------------------");
System.out.println("电影名:" + movies[i].getName());
System.out.println("评分:" + movies[i].getScore());
System.out.println("地区:" + movies[i].getArea());
System.out.println("类型:" + movies[i].getType());
System.out.println("导演:" + movies[i].getDirector());
System.out.println("主演:" + movies[i].getActor());
}
}
}