7.类与对象

本章目标

  • 面向对象
  • 类的定义
  • 封装性
  • 方法重载

本章内容

我们用String保存多个人的信息如下:

 String p1="1-姚明-男-43-226";
 String p2="2-刘翔-男-40-189";
 String p3="3-朱婷-女-29-198";

请输出此人的性别和年龄? split()

我们发现这些信息都有具体共同的特殊:

  • 首先都是人类
  • 其次都有编号、姓名、性别、年龄、身高
  • 无论姚明、刘翔、朱婷都是人类的一个具体实体

那么我们能不以设计出一个结构,体现出这种关系?这就是我们接下来要讲的类与对象

一、面向对象

面向对象是众多开发范式中的一种。除了面向对象,还有面向过程、指令式编程和函数式编程等,在所有的开发范式中,我们接触最多的还是面向过程和面向对象两种

1、面向过程(了解)

面向过程(Procedure Oriented)是一种以过程为中心的编程思想,是一种自顶而下的编程模式。最典型的面向过程的编程语言就是C语言。

简单地说,在面向过程的开发范式中,程序员需要把问题分解成一个个步骤,每个步骤用函数实现,依次调用即可。

在进行面向过程编程时,可以先定义一个函数,然后使用诸如if-else、for-each等方式执行代码。

  • 基于面向过程进行的软件开发,其代码都是流程化的,可以明确地看出第一步做什么、第二步做什么。**这种方式的代码执行起来效率很高。

但是,面向过程同时存在代码重用性低、扩展能力差、后期维护难度比较大等问题。

2、面向对象程序设计(OOP)

面向对象程序设计(Object Oriented Programming)是当今主要的程序设计方法,取代了早期的结构化程序设计开发成为应用程序开发的主流。

  • 而从OOP的思路出发,认为程序是由若干对象构成的(这些对象有自己的属性和能完成的操作):
  • 每一个对象仅负责一组相关的任务,如果它需要完成自身功能之外的操作,那么它应该去请求另一个能满足其要求的对象。
  • 一个对象请求另一个对象的工作方式,在Java中是以方法调用的形式实现的。
  • 在方法调用的过程中,调用者不必关心被调用的对象是如何实现功能,只要被调用的对象能满足要求就可以了。

3、类

一句话概念类:类是一种抽象的数据类型,是用于描述具有相同属性和行为的对象的集合。

  • 类来自对现实问题中对象的模拟和抽象,主要用来描述该实体(对象)具有哪些属性,哪些功能
  • 类可以看做是一种数据类型,运行方式与基本数据类型一样:初始化变量,随后使用变量
  • 除了使用系统类库提供了内置的数据类型之外,程序员可以通过自己定义类型来适应不同的问题
  • 类可以看做是对象的设计蓝图或是模板,一旦建立起类(完成了对现实问题抽象过程),就可以在程序中创建任意数量的对象,然后使用这些对象解决问题
  • 通过类构造对象的过程称之为创建类的实例

4、对象

Java是一门纯面向对象的语言,在面对对象的世界里,一切皆为对象。Java中有一句话叫万事万物皆对象,对象可以是现实生活中的一个物理对象,还可以是某一类概念实体的实例。

例如:一辆汽车、一个人、一本书,乃至一种语言、一个图形、一种管理方式,都可以作为一个对象。

对象的基本特性:

  • 行为:可以执行哪些操作(或者说提供了哪些方法可以被调用),相同类型的对象都拥有相同的行为;
  • 状态:在对象内部保存的,可以描述对象当前各种特征的信息,对象的状态必须通过方法调用来修改,反映行为对对象本身的影响;
  • 标识:对象的唯一性,任何对象都应该是与众不同的,即使存在状态、类型相同另一个对象。

5、OOP中对象特征

  • 将对象看做是特殊的变量,可以在内部存储数据,还可以完成特定的操作
  • 对象具有状态(内部数据)、行为(可供调用的方法)和标识(可以和其他相同类型的对象区分开来)
  • 程序是对象的集合,通过相互调用各自的功能来协作解决实际问题每个对象都有其类型信息:
  • 每个对象都是某个类的一个实例,类型信息决定了对象能提供的功能(能被调用的方法)
  • 同一类型的所有对象都可以提供同样的功能
  • 每个对象都有自己的数据,这些数据由其他对象构成:
  • 可以在程序中利用现有的对象搭建起更为复杂的对象

6、类与对象关系图

image

二、类的定义

1、基本格式

类Java程序的组织单元,class是定义类的关键字

1.1、定义一个类的步骤:

  1. 定义类名
  2. 编写类的属性
  3. 编写类的方法

1.2、通用格式

类定义的通用格式 如下:

  [public] class 类名称 {
       // 成员变量
       访问控制符 数据类型 变量名称;
       // 成员方法
       访问控制符 返回值数据类型 函数名称(参数列表) {
           函数体;
       } ...
 }

访问控制符:public、private、protected、default(默认)

2、类的创建及使用

2.1、创建Person类

人类有编号,姓名,年龄,身高,体重等属性

 public class Person {
     int id;
     String name;
     String sex;
     int age;
 
     public void play() {
         System.out.println("跑步!");
     }
 }

2.2、创建对象的过程

创建对象的过程就是实例化类的过程。充分运用类的模板特性,用类来生产出它的实例

创建对象时,需要做三件事:

  1. 对象的声明
  2. 对象的实例化
  3. 对象的初始化(本章暂不讲解)

2.3、对象声明

声明对象就是声明一个对象类型的变量,并指明该对象所属的类,该变量用来保存一个指向实际对象的引用。

声明对象变量的格式如下:

 类名  变量名;

示例

 Person person;

注意:上面声明的变量实际上并没有指向任何一个对象,必须用一个对象的引用来初始化变量后才可以使用

2.4、对象的实例化

使用new创建类的一个对象

 new 类名();

示例

 Person person  = new Person();

2.5、使用对象

使用.进行以下操作

给对象的属性赋值:

 对象名.属性

调用对象的方法:

对象名.方法名()

示例

public class Test {

    public static void main(String[] args) {
        Person person = new Person();
        person.id = 1001;
        person.name = "姚明";
        person.age = 43;
        person.sex = "男";
        person.height = 226;
        System.out.println("性别=" + person.sex);
        System.out.println("年龄=" + person.age);

    }

}

3、案例 (贯穿项目相关)

怎样用自定义Employee类型来保存一个人的id,name,sex,age,salary信息?

请输出此人的性别和年龄?

public class Employee {
    int id;
    String name;
    String sex;
    int age;
    double salary;

    public void woking() {
        System.out.println("工作!工作!工作!");
    }
}

三、Java三大特性之封装性

我们的Person实体类目前还有很多问题:

对象的属性赋值随意性太强 :比如可以给年龄赋值为负数,或远超人的最大寿命。性别可以除了男女之外还能输出其它内容

Java的三大特性:封装继承多态

我们暂时只讲封装性

1、封装的相关概念

封装:即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别。

  • 封装可以被认为是一个保护屏障,防止该类的代码和数据被外部类定义的代码随机访问。
  • 要访问该类的代码和数据,必须通过严格的接口控制。
  • 封装最主要的功能在于我们能修改自己的实现代码,而不用修改那些调用我们代码的程序片段。
  • 适当的封装可以让程式码更容易理解与维护,也加强了程式码的安全性。

image

优点

  • 良好的封装能够减少耦合。
  • 类内部的结构可以自由修改。
  • 可以对成员变量进行更精确的控制。
  • 隐藏信息的实现细节。

2、封装的实现

封装是隐藏类中的属性和方法的过程。

对象内部可以访问自己的属性,但程序只能通过调用对象的方法来修改其状态。

封装是提高代码重用性和可靠性的关键,可以保证一个类发生内部修改时,只要它提供的操作方法不变,就不会对程序的其他部分产生影响。

image

示例代码

public class Person {
    private int id;
    private String name;
    private String sex;
    private int age;
    private double height;

    public void woking() {
        System.out.println("工作!工作!工作!"+age);
    }
}

这种情况下,外界就无法方法了,但程序内部是可以访问,我们又想让外界能够访问,该怎么办呢?

测试

测试类中只能调用working方法

public class Test {

    public static void main(String[] args) {
        Person person = new Person();
        person.woking();

    }

}

3、访问属性

对于通过private访问控制符修改的成员属性,在需要的时候可以通过设置方法(setter)和访问方法(getter)从类的外部进行访问:

3.1、设置方法:

方法名为 set+属性名,属性名的首字母大写

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

3.2、访问方法:

方法名为 get+属性名,属性名的首字母大写

public String getName() {
    return name;
}

3.3、示例

public class Person {
    private int id;
    private String name;
    private String sex;
    private int age;
    private double height;

    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 String getSex() {
        return sex;
    }

    public void setSex(String sex) {
        this.sex = sex;
    }

    public int getAge() {
        return age;
    }

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

    public double getHeight() {
        return height;
    }

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

    public void woking() {
        System.out.println("工作!工作!工作!");
    }
}

3.4、测试

public class Test {

    public static void main(String[] args) {
        Person person = new Person();
        person.setId(1001);
        person.setName("姚明");
        person.setAge(43);
        person.setSex("男");
        person.setHeight(226);
        System.out.println("性别=" + person.getSex());
        System.out.println("年龄=" + person.getAge());

    }

}

4、案例 (贯穿项目相关)

1、用户性别只能为男或女,如果是其它值默认为男

2、用户年龄要求在18到65之间,超过范围,默认18岁

  • 示例:

    public class Employee {
    private int id;
    private String name;
    private String sex;
    private int age;
    private double salary;

    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 String getSex() {
        return sex;
    }
    
    public void setSex(String sex) {
        if("男".equals(sex) || "女".equals(sex)) {
            this.sex = sex;
        }else {
            this.sex = "男";
        }
    
    }
    
    public int getAge() {
        return age;
    }
    
    public void setAge(int age) {
        if(age>=18 && age<=65) {
            this.age = age;
        }else {
            this.age = 18;
        }
    
    }
    
    public double getSalary() {
        return salary;
    }
    
    public void setSalary(double salary) {
        this.salary = salary;
    }
    
    public void woking() {
        System.out.println("工作!工作!工作!");
    }
    

    }

  • 测试

    public class Test {

    public static void main(String[] args) {
        Employee emp = new Employee();
        emp.setId(1001);
        emp.setName("姚明");
        emp.setAge(43);
        emp.setSex("男");
        emp.setHeight(226);
        System.out.println("性别=" + emp.getSex());
        System.out.println("年龄=" + emp.getAge());
    
    }
    

    }

四、方法重载

1、什么是方法重载

在工具类Scanner中就有很多重载的示例

Java中允许进行方法重载,即在同一个类中存在相同名称的方法,在实际使用方法时根据参数列表的不同确定实际调用的版本:

方法重载的特征:

  • 在同一个类中定义
  • 方法名相同
  • 方法的参数列表不同(参数列表不一致包括:数据类型的顺序、数量、类型不一致)

注:是变量的类型不同,而不是变量的名字

2、案例 (贯穿项目相关)

2.1、创建消费者类

包含两个重载的方法:

buyProduct(int amount)用户正常购物: 用户购买之后按照一定比率累计积分,比如10元一积分

buyProduct(int amount, int multiple)用户购物特惠商品时:商家搞促销,用户购买可以获得双倍积分奖励

package com.woniuxy.hrms;

public class Customer {
    private int id;
    private String name;
    private int point = 1000;

    /**
     * 用户正常购物: 用户采购之后按照一定比率累计积分
     *
     * @param amount 金额
     */
    public void buyProduct(int amount) {
        point += amount / 10;
    }

    /**
     * 用户购物特惠商品时: 双倍积分奖励
     *
     * @param amount
     * @param mul 位数
     */
    public void buyProduct(int amount, int multiple) {
        point += amount / 10 * mul;
    }

    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 int getPoint() {
        return point;
    }

    public void setPoint(int point) {
        this.point = point;
    }

}

2.2、调用

public class Test {

    public static void main(String[] args) {
        // 客户一:正常消费,后台调用第一个方法
        Customer customerA = new Customer();
        customerA.buyProduct(1000);
        System.out.println("客户A消费后积分="+customerA.getPoint());
        // 客户一:优惠券消费,后台调用第二个方法,按消费金额除1000送积分
        Customer customerB = new Customer();
        customerB.buyProduct(1000, 2);
        System.out.println("客户B消费后积分="+customerB.getPoint());

    }

}

2.3、结果

客户A消费后积分=1100
客户B消费后积分=1200

思维导图

image

posted @ 2025-02-25 15:36  icui4cu  阅读(14)  评论(0)    收藏  举报