2day07——面向对象基础

各位同学,恭喜大家!!!大家学习完前面的课程后,说明Java的基础语法就全掌握了。

接下来,我们要学习的是Java中最核心的课程——面向对象编程

今日课程

1、什么是面向对象

2、面向对象的好处?

3、面向对象的执行原理★★

4、面向对象的注意事项

5、this关键字的使用

6、面向对象的三大特性--封装

7、实体JavaBean

8、综合案例

9、成员变量和局部变量的区别★★

一、面向对象入门

导入:各位同学,为什么说面向对象是Java最核心的课程呢?因为写Java程序是有套路的,而面向对象就是写Java程序的套路;你如果不知道面向对象编程,那么你Java语言就算白学了。

那这种编程套路是咋回事呢? 接下来,我们通过一个案例快速的认识一下。

问题:

什么是面向对象?什么是面向过程?

总结:

按照我们之前的写法,对应的编程思维被称为面向过程。面向就是着重点在于过程。比如去吃面这个事情。 \1. 需要找面馆 \2. 需要找服务员下单 \3. 等厨房做完 \4. 等服务员端上来 行为是在过程中产生的,这种思想被称为面向过程编程。 如果是面向对象的话,那么我们的核心就是找对象。对于这个事情我们的做法就是: \1. 找面馆 \2. 自己等着吃 从上面可以得到吃面这个事情,着重点在于对象,一个对象是面馆 ,一个对象是自己。这个过程产生的行为都属于对象的方法,这个就是面向对象的思想。

总结一些:所谓编写对象编程,就是把要处理的数据交给对象,让对象来处理。

二、深刻认识面向对象

导入:好的各位同学,在上一节课我们已经用面向对象的编程套路,处理了学生数据。接下来我们就要搞清楚,面向对象的几个最核心问题了。

问题:

我们把这三个问题搞明白,那么你对面向对象的理解就很到位。

总结:

2.1 面向对象编程有什么好处?

凡事找对象的编程套路,更加符合人类思维习惯,编程也会更直观。

任何一个对象都可以包含一些数据,数据属于哪个对象,就由哪个对象来处理。

2.2 程序中对象到底是个啥?对象是怎么出来的?

说完面向对象编程有什么好处之后,这里有同学可能会有问题了,你刚才举的例子中,“汽车”、“手机”、“蔡徐坤”是一个实实在在的东西,你说是一个对象好理解。那我们程序中的对象到底是个啥呢?

对象实质上是一种特殊的数据结构。这种结构怎么理解呢?

    • 类的理解
      • 类是对现实生活中一类具有共同属性和行为的事物的抽象
      • 类是对象的数据类型,类是具有相同属性和行为的一组对象的集合
      • 简单理解:类就是对现实事物的一种描述
    • 类的组成
      • 属性:指事物的特征,例如:手机事物(品牌,价格,尺寸)
      • 行为:指事物能执行的操作,例如:手机事物(打电话,发短信)
  • 类和对象的关系
    • 类:类是对现实生活中一类具有共同属性和行为的事物的抽象
    • 对象:是能够看得到摸的着的真实存在的实体
    • 简单理解:类是对事物的一种描述,对象则为具体存在的事物

一句话总结:对象可以理解成一张数据表,而数据表中可以有哪些数据,是有类来设计的。

三、对象在计算机中的执行原理

导入:各位同学,前面我们已经带同学写了面向对象的代码,也知道对象到底是咋回事。如果我们再搞清楚对象在计算机中的执行原理,那我们对面向对象的理解就更加专业了。

问题:

对象在计算机中的执行原理

总结:

按照我们之前讲的数组的执行原理,数组变量记录的其实数数组在堆内存中的地址。其实面向对象的代码执行原理和数组的执行原理是非常类似的。

image-20221008192133165 image-20221008192154939 image-20221008192822410

四、类和对象的一些注意事项

导入:各位同学,前面几节课我们已经入门了。接下来,关于面向对象有一些细枝末节的东西需要给大家交代一下。

问题

类和对象的一些注意事项

总结

我把这些注意事项已经列举在下面了,我们把几个不好理解的解释一下就可以了(标记方框),其他的大大家一看就能理解。

第一条:一个代码文件中,可以写多个class类,但是只能有一个是public修饰,且public修饰的类必须和文件名相同。

假设文件名为Demo1.java,这个文件中假设有两个类Demo1类和Student类,代码如下

//public修饰的类Demo1,和文件名Demo1相同
public class Demo1{
    
}

class Student{
    
}

**第二条:**对象与对象之间的数据不会相互影响,但是多个变量指向同一个对象会相互影响。

如下图所示,s1和s2两个变量分别记录的是两个对象的地址值,各自修改各自属性值,是互不影响的。

如下图所示,s1和s2两个变量记录的是同一个对象的地址值,s1修改对象的属性值,再用s2访问这个属性,会发现已经被修改了。

五、this关键字

导入:各位同学,接下来我们学习几个面向对象的小知识点,这里我们先认识一下this关键字是什么含义,再说一下this的应用场景。

问题:

this是什么呢?

this的应用场景?

总结:

在总结上面的问题之前,我们要先了解this的运行流程,看下图

image-20221008194153471 image-20221008194209583 image-20221008194231228 image-20221008194407880 image-20221008194421845 image-20221008194457559 image-20221008194519326

this是什么呢?

this就是一个变量,用在方法中,可以拿到当前类的对象。

哪一个对象调用方法方法中的this就是哪一个对象

this有什么用呢?

用来解决对象的成员变量与方法内部变量的名称一样时,导致访问冲突问题的。

关于this关键字我们就学习到这里,重点记住这句话:哪一个对象调用方法方法中的this就是哪一个对象

六、构造器

好同学们,接下来我们学习一个非常实用的语法知识——叫做构造器。

问题:

关于构造器,我们掌握下面几个问题就可以了:

  1. 什么是构造器?
  2. 掌握构造器的特点?
  3. 构造器的应用场景?
  4. 构造器有哪些注意事项?

我们一个问题一个问题的来学习,先来学习什么是构造器?

  • 什么是构造器?

    构造器其实是一种特殊的方法,但是这个方法没有返回值类型,方法名必须和类名相同。

    如下图所示:下面有一个Student类,构造器名称也必须叫Student;也有空参数构造器,也可以有有参数构造器。

格式:

1.方法名与类名相同,大小写也要一致

2.没有返回值类型,连void都没有

3.没有具体的返回值(不能由retrun带回结果数据)

认识了构造器之后,接着我们看一下构造器有什么特点。

  • 构造器的特点?

    在创建对象时,会调用构造器。

    也就是说 new Student()就是在执行构造器,当构造器执行完了,也就意味着对象创建成功。

    当执行new Student("播仔",99)创建对象时,就是在执行有参数构造器,当有参数构造器执行完,就意味着对象创建完毕了。

关于构造器的特点,我们记住一句话:new 对象就是在执行构造方法

  • 构造器的应用场景?

    其实构造器就是用来创建对象的。可以在创建对象时给对象的属性做一些初始化操作。如下图所示:

  • 构造器的注意事项?

    学习完构造器的应用场景之后,接下来我们再看一下构造器有哪些注意事项。

    1.在设计一个类时,如果不写构造器,Java会自动生成一个无参数构造器。
    2.一定定义了有参数构造器,Java就不再提供空参数构造器,此时建议自己加一个无参数构造器。
    

关于构造器的这几个问题我们再总结一下。掌握这几个问题,构造方法就算完全明白了。

1.什么是构造器?
	答:构造器其实是一种特殊的方法,但是这个方法没有返回值类型,方法名必须和类名相			同。
	
2.构造器什么时候执行?
	答:new 对象就是在执行构造方法;

3.构造方法的应用场景是什么?
	答:在创建对象时,可以用构造方法给成员变量赋值

4.构造方法有哪些注意事项?
	1)在设计一个类时,如果不写构造器,Java会自动生成一个无参数构造器。
	2)一定定义了有参数构造器,Java就不再提供空参数构造器,此时建议自己加一个无参数构		造器。

七、封装性

各位同学,接下来我们再学习一个面向对象很重要的特征叫做——封装性。

问题:

1.private关键字作用?

2. 封装的作用和使用?

总结:

private关键字作用?

是一个权限修饰符

可以修饰成员(成员变量和成员方法)

private修饰的成员只能在本类中才能访问

案例

image-20221008211115976 image-20221008211211784

针对private修饰的成员变量,如果需要被其他类使用,提供相应的操作

l提供get变量名()方法,用于获取成员变量的值,方法用public修饰

l提供set变量名(参数)方法,用于设置成员变量的值,方法用public修饰

封装的作用和使用

所谓封装,就是用类设计对象处理某一个事物的数据时,应该把要处理的数据,以及处理数据的方法,都设计到一个对象中去。

image-20221008212420611 image-20221008212653159

关于封装我们就学习到这里了。

八、实体JavaBean

接下来,我们学习一个面向对象编程中,经常写的一种类——叫实体JavaBean类。我们先来看什么是实体类?

问题:

1.JavaBean实体类是什么?有啥特点

2.JavaBean的应用场景?

总结:

1. 什么是实体类?

实体类就是一种特殊的类,它需要满足下面的要求:

接下来我们按照要求,写一个Student实体类;

写完实体类之后,我们看一看它有什么特点? 其实我们会发现实体类中除了有给对象存、取值的方法就没有提供其他方法了。所以实体类仅仅只是用来封装数据用的。

知道实体类有什么特点之后,接着我们看一下它有哪些应用场景?

2. 实体类的应用场景

在实际开发中,实体类仅仅只用来封装数据,而对数据的处理交给其他类来完成,以实现数据和数据业务处理相分离。如下图所示

到这里,我们已经学习了JavaBean实体类的是什么,以及它的应用场景,我们总结一下

1.JavaBean实体类是什么?有啥特点
	JavaBean实体类,是一种特殊的;它需要私有化成员变量,有空参数构造方法、同时提供		getXxx和setXxx方法;
	
	JavaBean实体类仅仅只用来封装数据,只提供对数据进行存和取的方法
 
2.JavaBean的应用场景?
	JavaBean实体类,只负责封装数据,而把数据处理的操作放在其他类中,以实现数据和数		据处理相分离。

九、面向对象综合案例

学习完面向对象的语法知识之后。接下来,我们做一个面向对象的综合案例——模仿电影信息系统。

需求如下图所示

1. 想要展示系统中全部的电影信息(每部电影:编号、名称、价格)
2. 允许用户根据电影的编号(id),查询出某个电影的详细信息。

运行程序时,能够根据用户的选择,执行不同的功能,如下图所示

按照下面的步骤来完成需求

1. 第一步:定义电影类

首先每一部电影,都包含这部电影的相关信息,比如:电影的编号(id)、电影的名称(name)、电影的价格(price)、电影的分数(score)、电影的导演(director)、电影的主演(actor)、电影的简介(info)。

为了去描述每一部电影,有哪些信息,我们可以设计一个电影类(Movie),电影类仅仅只是为了封装电影的信息,所以按照JavaBean类的标准写法来写就行。

public class Movie {
    private int id;
    private String name;
    private double price;
    private double score;
    private String director;
    private String actor;
    private String info;

    public Movie() {
    }

    public Movie(int id, String name, double price, double score, String director, String actor, String info) {
        this.id = id;
        this.name = name;
        this.price = price;
        this.score = score;
        this.director = director;
        this.actor = actor;
        this.info = info;
    }

    public int getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

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

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }

    public double getScore() {
        return score;
    }

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

    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;
    }

    public String getInfo() {
        return info;
    }

    public void setInfo(String info) {
        this.info = info;
    }
}

2. 第二步:定义电影操作类

前面我们定义的Movie类,仅仅只是用来封装每一部电影的信息。为了让电影数据和电影数据的操作相分离,我们还得有一个电影操作类(MovieOperator)。

因为系统中有多部电影,所以电影操作类中MovieOperator,需要有一个Movie[] movies; 用来存储多部电影对象;

同时在MovieOperator类中,提供对外提供,对电影数组进行操作的方法。如printAllMovies()用于打印数组中所有的电影信息,searchMovieById(int id)方法根据id查找一个电影的信息并打印。

public class MovieOperator {
    //因为系统中有多部电影,所以电影操作类中,需要有一个Movie的数组
    private Movie[] movies;
    public MovieOperator(Movie[] movies){
        this.movies = movies;
    }

    /** 1、展示系统全部电影信息 movies = [m1, m2, m3, ...]*/
    public void printAllMovies(){
        System.out.println("-----系统全部电影信息如下:-------");
        for (int i = 0; i < movies.length; i++) {
            Movie m = movies[i];
            System.out.println("编号:" + m.getId());
            System.out.println("名称:" + m.getName());
            System.out.println("价格:" + m.getPrice());
            System.out.println("------------------------");
        }
    }

    /** 2、根据电影的编号查询出该电影的详细信息并展示 */
    public void searchMovieById(int id){
        for (int i = 0; i < movies.length; i++) {
            Movie m = movies[i];
            if(m.getId() == id){
                System.out.println("该电影详情如下:");
                System.out.println("编号:" + m.getId());
                System.out.println("名称:" + m.getName());
                System.out.println("价格:" + m.getPrice());
                System.out.println("得分:" + m.getScore());
                System.out.println("导演:" + m.getDirector());
                System.out.println("主演:" + m.getActor());
                System.out.println("其他信息:" + m.getInfo());
                return; // 已经找到了电影信息,没有必要再执行了
            }
        }
        System.out.println("没有该电影信息~");
    }
}

3. 第三步:定义测试类

最后,我们需要在测试类中,准备好所有的电影数据,并用一个数组保存起来。每一部电影的数据可以封装成一个对象。然后把对象用数组存起来即可。

public class Test {
    public static void main(String[] args) {
        //创建一个Movie类型的数组
        Movie[] movies = new Movie[4];
        //创建4个电影对象,分别存储到movies数组中
        movies[0] = new Movie(1,"水门桥", 38.9, 9.8, "徐克", "吴京","12万人想看");
        movies[1] = new Movie(2, "出拳吧", 39, 7.8, "唐晓白", "田雨","3.5万人想看");
        movies[2] = new Movie(3,"月球陨落", 42, 7.9, "罗兰", "贝瑞","17.9万人想看");
        movies[3] = new Movie(4,"一点就到家", 35, 8.7, "许宏宇", "刘昊然","10.8万人想看");
        
    }
}

准备好测试数据之后,接下来就需要对电影数据进行操作。我们已经把对电影操作先关的功能写到了MovieOperator类中,所以接下来,创建MovieOperator类对象,调用方法就可以完成相关功能。

继续再main方法中,接着写下面的代码。

// 4、创建一个电影操作类的对象,接收电影数据,并对其进行业务处理
MovieOperator operator = new MovieOperator(movies);
Scanner sc = new Scanner(System.in);
while (true) {
    System.out.println("==电影信息系统==");
    System.out.println("1、查询全部电影信息");
    System.out.println("2、根据id查询某个电影的详细信息展示");
    System.out.println("请您输入操作命令:");
    int command = sc.nextInt();
    switch (command) {
        case 1:
            // 展示全部电影信息
            operator.printAllMovies();
            break;
        case 2:
            // 根据id查询某个电影的详细信息展示
            System.out.println("请您输入查询的电影id:");
            int id = sc.nextInt();
            operator.searchMovieById(id);
            break;
        default:
            System.out.println("您输入的命令有问题~~");
    }
}

到这里,电影信息系统就完成了。 小伙伴们,自己尝试写一下吧!!

十、成员变量和局部变量的区别

各位同学,面向对象的基础内容咱们已经学习完了。同学们在面向对象代码时,经常会把成员变量和局部变量搞混。所以现在我们讲一讲他们的区别。

如下图所示,成员变量在类中方法外,而局部变量在方法中。


到这里,我们关于面向对象的基础知识就学习完了。面向对象的核心点就是封装,将数据和数据的处理方式,都封装到对象中; 至于对象要封装哪些数据?对数据进行怎样的处理? 需要通过类来设计。

需要注意的是,不同的人,对同一个对象进行设计,对象封装那些数据,提供哪些方法,可能会有所不同;只要能够完成需求,符合设计规范,都是合理的设计。