Java面向对象基础


面向对象

image-20230125172609599

面向对象并不是一个技术,而是一种编程的指导思想,让我们以什么形式 组织代码;以什么思路 解决问题。

为什么要学习面向对象?

因为生活中,我们解决问题时,就是采用这种指导思想去解决的,所以,我们写程序去解决问题时,如果也能采用这种指导思想,就会使编程变得非常简单,程序也便于人理解 。

比如有顾客去买手机,顾客是对象,售货员也是对象,钱是对象,手机也是对象。

image-20230125184136365

在我们前面的学习中,Scanner 和 Random都是 Java已经写好的类,但如果我们要解决的问题 Java 没有提供怎么办?

image-20230125213634727

面向对象,重点学什么?

  1. 学习自己如何设计对象
  2. 学习已有的对象如何使用

一、类和对象

1. 类的介绍

Java 中想要创建对象,必须先要有类的存在

类指的是一组相关属性和行为的集合,我们将其理解为是一张对象的设计图

image-20230125214038903

2. 类和对象的关系

  • 依赖关系:Java 中需要根据类,创建对象
  • 数量关系:一个类,可以创建出多个对象

3. 类的组成

  • 属性:
    • 成员变量:跟之前定义变量的格式一样只不过位置需要放在方法的外面
  • 行为:
    • 成员方法:跟之前定义方法的格式一样只不过需要去掉static关键字

下面我们定义了一个学生类,包含两个成员变量姓名、年龄;两个成员方法学习、吃饭。

package cn.edu.hgu.oop;

public class Student {
    //属性;姓名,年龄
    String name = "张三";
    int age = 23;

    //行为:学习,吃饭
    public void study() {
        System.out.println("学生学习...");
    }

    public void eat() {
        System.out.println("学生吃饭...");
    }
}

4. 创建对象和使用对象的格式

前面,我们创建了 Study 类,但是并不能直接运行,需要将类实例化——创建对象。

  1. 创建对象类名
对象名 = new 类名();
  1. 变量的使用格式
对象名.变量名;
  1. 方法的使用格式
对象名.方法名(实际参数);

我们来定义一个 StudyTest 类,用来创建对象和使用对象:

package cn.edu.hgu.oop;

public class StudyTest {
    public static void main(String[] args) {
        Student stu1 = new Student();

        System.out.println(stu1.name);
        System.out.println(stu1.age);

        stu1.study();
        stu1.eat();
    }

}

运行代码,输出结果为:

image-20230125215923781

细节:

  1. 打印对象名,可以看到对象的内存地址
  2. 成员变量就算没有赋值,也可以直接使用,使用的是对象的默认值

我们可以看到输出结果,但这个结果使我们提前写死的,这样不灵活,接下来我们来修改一下代码:

package cn.edu.hgu.oop;

public class StudyTest {
    public static void main(String[] args) {
        Student stu1 = new Student();

        stu1.name = "张三";
        stu1.age = 23;

        System.out.println(stu1.name);
        System.out.println(stu1.age);

        stu1.study();
        stu1.eat();

        System.out.println("-------------");

        Student stu2 = new Student();

        stu2.name = "李四";
        stu2.age = 18;

        System.out.println(stu2.name);
        System.out.println(stu2.age);

        stu2.study();
        stu2.eat();

    }

}

输出结果为:

image-20230125221102477

经过前面的学习,我们初步了解了类的定义与对象的创建和使用,下面我们通过两个案例来进行巩固。

案例1:手机

定义一个手机类 (Phone)

  • 属性: (品牌 brand,颜色 color, 价格 price)
  • 行为:
    • 打电话 (call):输出给 xxx 打电话
    • 发短信 (sendMessage):输出群发短信

编写一个手机测试类 (PhoneTest)

  • 创建两个手机对象, 并给属性赋值

    1. 小米, 白色, 4999

    2. 华为, 黑色, 6999

  • 赋值之后, 校验自己有没有赋值成功, 使用打印语句校验, 调用两个对象各自的成员方法

代码实现:

package cn.edu.hgu.oop;

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

    public void call(String name){
        System.out.println("给"+name+"打电话");
    }

    public void sendMessage(){
        System.out.println("群发短信");
    }
}

package cn.edu.hgu.oop;

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

        p1.brand="小米";
        p1.color = "白色";
        p1.price = 4999;

        System.out.println(p1.brand+"---"+p1.color +"---"+p1.price);

        p1.call("张三");
        p1.sendMessage();

        System.out.println("-----------");

        Phone p2 = new Phone();

        p2.brand="华为";
        p2.color = "黑色";
        p2.price = 6999;

        System.out.println(p2.brand+"---"+p2.color +"---"+p2.price);


        p2.call("王维");
        p2.sendMessage();
    }
}

输出结果为:

image-20230125224246512

案例2:图书

编写一个图书类 (Book)

  • 属性: 编号 (id) 书名(name) 价格 (price)
  • 行为: 展示 (show) 该方法中需要展示出图书的所有属性信息

编写一个图书测试类 (BookTest)

  • 创建 3 个图书对象, 分别赋值为

    (001, 三国, 88.88)

    (002, 水浒, 88.88)

    (003, 富婆通讯录, 10000)

  • 调用3个对象, 各自的show 方法展示属性信息

代码实现:

图书类(Book):

package cn.edu.hgu.oop;

public class Book {

    String id;
    String name;
    double price;

    public void show() {
        System.out.println("编号为:" + id + ",书名为:" + name + ",价格为:" + price);
    }

}

图书测试类(BookTest):

package cn.edu.hgu.oop;

public class BookTest {
    public static void main(String[] args) {
        Book b1 = new Book();
        b1.id = "001";
        b1.name = "三国";
        b1.price = 88.88;

        Book b2 = new Book();
        b2.id = "002";
        b2.name = "水浒";
        b2.price = 88.88;

        Book b3 = new Book();
        b3.id = "003";
        b3.name = "富婆通讯录";
        b3.price = 10000;

        b1.show();
        b2.show();
        b3.show();

    }
}

输出结果为:

image-20230131120552798

二、对象内存图

1. 单个对象内存图

image-20230131120956513

一开始 Student类 和 TestStudent 都在方法区,调用 main 方法,main 方法进入栈内存执行,调用 Student 类创建一个stu变量,在堆内存中新开辟一块空间,并对成员变量初始化,打印变量名会输出变量地址,打印成员变量会打印初始化变量值,根据地址对成员变量进行赋值,堆内存中的数据就会进行修改,再打印成员变量就会输出修改好的成员变量,调用成员方法,先进栈,执行完成后出栈。

2. 两个对象内存图

image-20230131124717792

image-20230131124954119

3. 两个引用指向相同内存图

image-20230131125341813

三、成员变量和局部变量

成员变量和局部变量的区别:

image-20230126072822945

四、this 关键字

1. this 可以解决的问题

定义一个 Student 类:

package cn.edu.hgu.mthis;

public class Student {
    String name;
    int age;

    public void sayHello(String name){
        System.out.println(name);
    }
}

定义一个测试类

package cn.edu.hgu.mthis;

public class ThisDemo {
    public static void main(String[] args) {
        Student stu = new Student();
        stu.name = "钢门吹雪";

        stu.sayHello("西域狂鸭");
    }
}

输出结果为:

image-20230131131701441

当局部变量和成员变量出现了重名的情况,Java 使用的是 就近原则

问题:非要使用成员变量,怎么ban?

解决:使用 this 关键字进行区分,this可以区分局部变量和成员变量的重名问题

image-20230131132726504

2. this 介绍

this 代表当前类对象的引用(地址)

this 关键字的作用:

  • this 可以调用本类成员(变量,方法)

    this.本类成员变量

    this.本类成员方法

  • this.的省略原则:

    本类成员方法:没有前提条件,this.可以直接省略

    本类成员变量:方法中没有出现重名的变量,this.才可以省略

3. this 内存图

image-20230131140658109

image-20230126094323598

五、构造方法

1. 构造方法概述

  • 构造器
    • 初始化一个新建的对象
    • 构建、创造对象的时候,所调用的方法
  • 格式:
    • 方法名与类名相同,大小写也要一致
    • 没有返回值类型,连void都没有
    • 没有具体的返回值(不能由return带回结果数据
  • 执行时机:
    • 创建对象的时候调用,每创建一次对象,就会执行一次构造方法
    • 不能手动调用构造方法

image-20230131141417113

2. 构造方法作用

本质作用:创建对象

结合构造方法执行时机:给对象中的属性(成员变量)进行初始化

3. 构造方法注意事项

①构造方法的创建

  • 如果没有定义构造方法,系统将给出一个默认的无参数构造方法
  • 如果定义了构造方法,系统将不再提供默认的构造方法

②构造方法的重载

  • 构造方法也是方法,允许重载关系出现

③推荐的使用方式

  • 无参数构造方法,和带参数构造方法,都自己手动给出
  • 构造方法不允许手动调用

六、封装

1. 面向对象三大特征

image-20230126151801533

这里我们先来学习封装。

封装:使用类设计对象时,将需要处理的数据,以及处理这些数据的方法, 设计到对象中。

计算出每一名学生的总成绩,展示学生的所有信息

id姓名年龄数学成绩语文成绩
1张三239087
2李四246991
public class Student {
    int id;
    String name;
    int age;
    double mathScore;
    double chineseScore;
    // 省略构造方法
    public double getTotalScore() {
        return mathScore + chineseScore;
    }
    
    public void showStudentInfos(){
        System.out.println("学号: " + id);
        System.out.println("姓名: " + name);
        System.out.println("年龄:" + age);
        System.out.println("数学成绩:" + mathScore);
        System.out.println("语文成绩:" + chineseScore);
    }
}

public class Test {
    public static void main(String[] args) {
        Student stu1 = new Student(1, "张三", 23,90,87);
        stu1.showStudentInfos();
        Student stu2 = new Student(2, "李四", 24,69,91);
        stu2.showStudentInfos();
    }
}

这样可以更好的维护数据;使用者无需关心内部实现, 只要知道如何使用即可。

2. 封装的设计规范

合理隐藏, 合理暴露

一辆车,展示给我们的是使用功能,其他的部件都隐藏起来了。

image-20230131143938012

3. 权限修饰符

我们在执行程序的时候,我们不想让对象直接调用某个方法,而是去间接使用它。

image-20230131144330129

  • private :同一个类中
  • (defalut):同一个类中,同一个包中
  • protected:同一个类中,同一个包中,不同包的子类
  • public :任意位置访问

4. 标准 JavaBean

JavaBean 标准:

  1. 这个类中的成员变量都要私有,并且要对外提供相应的getXxx ,setXxx方法
  2. 类中提供无参, 带参构造方法。

实体类的应用场景是什么?

实体类只负责数据存取,而对数据的处理交给其他类来完成,以实现数据和数据业务处理相分离。

image-20230131144816241

安装快速生成JavaBean的插件:

image-20230129100307074

image-20230131145007772

生成后的代码:

package cn.edu.hgu.domain;

public class Student {
    private String name;
    private int age;

    public Student() {
    }

    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }

    /**
     * 获取
     *
     * @return name
     */
    public String getName() {
        return name;
    }

    /**
     * 设置
     *
     * @param name
     */
    public void setName(String name) {
        this.name = name;
    }

    /**
     * 获取
     *
     * @return age
     */
    public int getAge() {
        return age;
    }

    /**
     * 设置
     *
     * @param age
     */
    public void setAge(int age) {
        this.age = age;
    }

    public String toString() {
        return "Student{name = " + name + ", age = " + age + "}";
    }
}

七、综合案例

面向对象综合案例-模仿电影信息系统

需求

  • 展示系统中的全部电影(每部电影展示:名称、评分)。
  • 允许用户根据电影编号(id)查询出某个电影的详细信息。

image-20230131151545907

image-20230131151552667

电影需要展示的信息有:

  • int id; 编号
  • String title; 片名
  • String time; 时间
  • double score; 评分
  • String area; 地区
  • String type; 类型
  • String director; 导演
  • String starring; 主演

代码实现:

package cn.edu.hgu.domain;

public class Movie {
    private int id;
    private String title;
    private String time;
    private double score;
    private String area;
    private String type;
    private String director;
    private String starring;


    public Movie() {
    }

    public Movie(int id, String title, String time, double score, String area, String type, String director, String starring) {
        this.id = id;
        this.title = title;
        this.time = time;
        this.score = score;
        this.area = area;
        this.type = type;
        this.director = director;
        this.starring = starring;
    }

    /**
     * 获取
     *
     * @return id
     */
    public int getId() {
        return id;
    }

    /**
     * 设置
     *
     * @param id
     */
    public void setId(int id) {
        this.id = id;
    }

    /**
     * 获取
     *
     * @return title
     */
    public String getTitle() {
        return title;
    }

    /**
     * 设置
     *
     * @param title
     */
    public void setTitle(String title) {
        this.title = title;
    }

    /**
     * 获取
     *
     * @return time
     */
    public String getTime() {
        return time;
    }

    /**
     * 设置
     *
     * @param time
     */
    public void setTime(String time) {
        this.time = time;
    }

    /**
     * 获取
     *
     * @return score
     */
    public double getScore() {
        return score;
    }

    /**
     * 设置
     *
     * @param score
     */
    public void setScore(double score) {
        this.score = score;
    }

    /**
     * 获取
     *
     * @return area
     */
    public String getArea() {
        return area;
    }

    /**
     * 设置
     *
     * @param area
     */
    public void setArea(String area) {
        this.area = area;
    }

    /**
     * 获取
     *
     * @return type
     */
    public String getType() {
        return type;
    }

    /**
     * 设置
     *
     * @param type
     */
    public void setType(String type) {
        this.type = type;
    }

    /**
     * 获取
     *
     * @return director
     */
    public String getDirector() {
        return director;
    }

    /**
     * 设置
     *
     * @param director
     */
    public void setDirector(String director) {
        this.director = director;
    }

    /**
     * 获取
     *
     * @return starring
     */
    public String getStarring() {
        return starring;
    }

    /**
     * 设置
     *
     * @param starring
     */
    public void setStarring(String starring) {
        this.starring = starring;
    }
    
}

MovieService类

package cn.edu.hgu.test;

import cn.edu.hgu.domain.Movie;

import java.util.Scanner;

public class MovieService {
    Scanner sc = new Scanner(System.in);
    Movie[] movies;

    public MovieService(Movie[] movies) {
        this.movies = movies;
    }

    /**
     * 启动电影信息管理系统
     */
    public void start() {

        lo:
        while (true) {
            System.out.println("----------电影信息系统----------");
            System.out.println("请输入您的选择:");
            System.out.println("1. 查询全部电影信息");
            System.out.println("2. 根据id查询电影信息");
            System.out.println("3. 退出");

            int choice = sc.nextInt();

            switch (choice) {
                case 1:
                    queryMovieInfos();
                    break;
                case 2:
                    queryMovieInfoById();
                    break;
                case 3:
                    System.out.println("感谢您的使用,再见!");
                    break lo;
                default:
                    System.out.println("您的输入有误,请检查");
                    break;
            }
        }
    }

    /**
     * 此方法根据电影编号,查询电影详情信息
     */
    private void queryMovieInfoById() {
        // 1.键盘录入用户输入的编号
        System.out.println("请输入您要查询的电影编号:");
        int id = sc.nextInt();
        // 2.遍历数组,从数组中查询电影信息
        for (int i = 0; i < movies.length; i++) {
            Movie movie = movies[i];
            if (movie.getId() == id) {
                // 3.将找到的电影信息,打印在控制台
                System.out.println(movie.getId() + "---" + movie.getTitle() + "---"
                        + movie.getTime() + "---" + movie.getScore() + "---" + movie.getArea() + "---"
                        + movie.getType() + "---" + movie.getDirector() + "---" + movie.getStarring());
                return;
            }
        }
        System.out.println("您输入的编号不存在,请检查!");
    }

    /**
     * 展示系统中全部的电影(名称,评分)
     */
    private void queryMovieInfos() {
        // 1.遍历数组,取出每一个电影对象
        for (int i = 0; i < movies.length; i++) {
            Movie movie = movies[i];
            // 2.通过电影名称,调用内部 getXxx方法,获取信息并打印
            System.out.println(movie.getTitle() + "---" + movie.getScore());
        }
    }
}

Test类

package cn.edu.hgu.test;

import cn.edu.hgu.domain.Movie;

public class Test {
    public static void main(String[] args) {
        Movie movie1 = new Movie(1, "东八区的先生们", "2022", 2.1, "中国大陆", "剧情 喜剧", "夏睿", "张翰 王晓晨");
        Movie movie2 = new Movie(2, "上海堡垒", "2019", 2.9, "中国大陆", "爱情 战争 科幻", "滕华涛", "鹿晗 舒淇");
        Movie movie3 = new Movie(3, "纯洁心灵·逐梦演艺圈", "2015", 2.2, "中国大陆", "剧情 喜剧", "毕志飞", "朱一文 李彦漫");

        Movie[] movies = {movie1, movie2, movie3};

        MovieService movieService = new MovieService(movies);
        movieService.start();
    }
}

运行结果为:

image-20230131162427900

``

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

W_chuanqi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值