Java的第五篇文章——面向对象的编程思想(类和对象)

简介: Java的第五篇文章——面向对象的编程思想(类和对象)

第五章 面向对象的编程

学习目标

  • 理解面向对象的编程思想
  • 创建类和对象
  • 包是什么
  • 类中的成员
  • 对象的内存分析

1.面向对象思想

1.1 面向过程的思想

1.1.1 面向过程程序特点

在顺序、分支、循环结构中,操作变量中存储的数据

1.1.2 面向过程思想对应的问题

面向过程这种程序设计理念,对应现实生活中某一个点上具体的问题,特别是对应解决问题过程中具体的操作步骤。

1.1.3 面向过程程序的不足

最大的不足:整个系统各个组成部分之间『耦合』太严重。

  • 从开发角度来说:对任何一个细微的地方做修改、调整、升级都会不可避免的影响到其他部分。
  • 从运行角度来说:整个系统中有任何一个数据发生了变化,相关的很多部分都要重新运算,非常浪费性能。

1.1.4 本质

从面相过程的思想发展到面向对象的思想根本原因就是因为随着时代、市场等方方面面的发展,要求程序员编写更加复杂的程序,设计更加庞大的系统。

由非常多组成部分有机结合在一起的系统是面向过程代码无法容纳的。

1.2 面向对象

1.2.1 关键

面向对象的设计理念、编程思想非常贴合人平时认识世界、思考问题时的思维方式。

一切皆对象:现实世界中的所谓『东西』投射到代码中就是『对象』

  • 工业产品:一辆汽车中的各个组成部分、各个部件中各种的零件
  • 日常生活:做饭时使用的厨具、食材、餐具等等“东西”

所以有了面向对象的设计理念和编程思想,我们就可以在开发过程中,大致保持和平时一样的思维方式来设计系统、编写代码。

1.2.2 类

程序中的『类』,对应到生活中就是对同一类事物的一个统一的『分类名称』。

1.2.3 类和对象的关系

  • 从抽象和具体的角度来说:
  • 类:抽象描述
  • 对象:具体实体,所以对象也被称作:『类的实例』
  • 从设计图和产品的角度来说:
  • 类:生产产品的设计图
  • 对象:按照设计图生产出来的一个具体的产品

使用汽车设计图可以生产汽车产品;使用汽车类可以创建汽车对象。

使用月饼模具可以生产月饼产品。

使用月饼类可以创建月饼对象。

1.3 小结

一句话:面向对象的思想最根本的目的就是为了让程序能够更好的『描述』现实世界程序只有做到了尽量逼真的描述现实世界,才能让程序解决现实生活中真实存在的问题。所以这个思想有两方面最大的好处:

  • 更好的描述现实世界
  • 更符合人平时的思维方式

2.创建类和对象

2.1 类的组成部分

2.1.1 属性(对应程序中的数据)

通过程序中的各种数据类型,来描述一个类的『特征』,例如:汽车的颜色、汽车的排量、汽车的价格……

2.1.2 方法(对应程序中的操作)

通过程序中的方法(也就是面向过程视角中的函数),来执行这个类的对象能够做的『动作』。例如:汽车的行驶、汽车的鸣笛、汽车的启动、汽车的停泊……

属性 行为
毛色 品种 年龄 体重 性别 吃猫粮 抓老鼠 走猫步 撒娇 喵喵
品种 年龄 高度 功用 生长 落叶 结果 枯萎
英文名 面向过程角度名称 面向对象角度名称
Filed 成员变量 属性
Method 成员函数 方法

2.2 声明一个类(空)

2.3 声明一个类(有属性、方法)

public class Person {
    // 属性/成员变量
    // 暂时先不管声明属性的具体规则,像以前一样声明变量先使用
    // 这个成员变量即使没有初始化,系统也会为它分配初始值
    // int类型的初始值是0
    int weight;
    // 方法/成员函数
    // 暂时先不管声明函数的具体规则,先声明一个最简单的
    // public:表示这个方法可以在任何地方被调用
    // void:表示这个方法没有返回值
    // (int food):声明这个方法在被调用时可以传入的参数
    public void eat(int food) {
        weight = weight + food;
    }
    public void say() {
        System.out.println("我现在的体重是:" + weight);
    }
}

2.4 声明一个对Person进行测试的类

public class PersonTest {
    public static void main(String[] args) {
        // 1.创建Person类的对象
        // 第一步:声明一个Person类这个类型的变量
        // 第二步:使用new关键字创建Person类的对象,对象赋值给第一步声明的变量
        //          在new关键字后面的,是Person类的『构造器』
        //          构造器在以后还会介绍更多细节,现在大家就按照:类名()的格式写就行
        Person person = new Person();
        // 2.调用Person对象的eat()方法:让这个人吃饭
        // 调用有参数方法的格式:指向对象的那个变量.方法名(参数)
        person.eat(5);
        // 3.调用Person对象的say()方法:让这个人说说他的体重
        // 调用无参数方法的格式:指向对象的那个变量.方法名()
        person.say();
        // 4.直接修改weight属性
        // 在类之外的其他地方是否可以操作类的属性,取决于属性的修饰符
        // 在将来学习了面向对象的『封装』特性后,我们会知道,在类的外部不建议直接操作类的属性
        person.weight = 20;
        person.say();
    }
}

3.包

3.1 包的作用

3.1.1 区分同名的类

包最重要的作用:区分同名的类。

3.1.2 将不同的类放在不同包下

3.2 简单类名和全类名

  • 简单类名:不带包名的类名
  • 全类名:包名.类名

全类名举例:

com.atguigu.bookstore.entity.Book

java.awt.print.Boo

4.类中的属性

4.1 声明属性的语法格式

(1)修饰符 数据类型 属性名;

(2)修饰符 数据类型 属性名 = 初始化值;

4.2 初始化值

声明一个属性时,如果没有明确的对这个属性进行初始化值的设置,那么系统会给这个属性设置默认值。所以如果有确定的需要可以设置属性的默认值,如果没有特殊需要,不设置也行。

4.3 数据类型

  • 基本数据类型
  • 引用数据类型

4.4 权限修饰符

权限修饰符不仅对类的属性有要求,对类中的方法的要求是完全一样的:

修饰符名称 含义 本类 同包其他类 子类 同工程其他类
private 私有 × × ×
default 缺省 × ×
protected 受保护 ×
public 公共

4.5 属性名

属性也叫成员变量,所以属性名作为标识符适用变量的标识符规则和规范。

5.对象的内存分析

public class Cat {
    private String catName = "dingdang";
    int weight;
    public void say(String master) {
        boolean emotion = true;
        if (emotion) {
            int food = 5;
            System.out.println("My name is " + catName + ",I want food:" + food);
        }
    }
}

5.1 基本情况

5.1.1 声明变量

// 1.声明Cat类型的变量
Cat cat;

5.1.2 创建对象

大家可以记住:只要看见使用了new关键词,就表示在堆内存中一定开辟了新的空间,一定创建了新的对象。

// 2.给Cat类型的变量赋值一个Cat类型的对象
Cat cat = new Cat();

5.1.3 调用方法

// 3.调用Cat对象的方法
cat.say("tom");

5.1.4 say()方法执行完成

局部变量就会被释放掉

5.1.5 main()方法执行完成

main()方法中的cat局部变量也会被释放掉。然后Cat对象就成了“断了线的风筝”被垃圾回收机制回收。

5.2 创建两个对象

证明:两个对象在堆空间中分别有自己的副本,分别进行操作时互不影响。

5.2.1 创建第一个对象

Cat cat01 = new Cat();

5.2.2 创建第二个对象

Cat cat02 = new Cat();

5.2.3 第一个变量设置属性

cat01.weight = 10;

5.2.4 第二个变量设置属性

cat02.weight = 20;

5.3 两个变量指向同一对象

Cat cat03 = new Cat();
Cat cat04 = cat03;

分别用两个变量修改weight属性:

cat03.weight = 66;

cat04.weight = 88;

5.4 变量置空

5.4.1 将cat04置空

cat04 = null;

5.4.2 将cat03置空

cat03 = null;

6.方法

6.1 概念

6.1.1 代码复用

6.1.2 参数和返回值

方法的参数和返回值都不是必须有的,根据需要设置。

  • 方法的参数:我们命令方法替我们干活的时候,有时需要给方法提供一些数据
  • 形式参数:声明方法时指定的参数,用来说明这个方法可以接受哪些参数(简称形参)
  • 实际参数:调用方法时实际传入的参数,用于方法执行过程中实际的运算(简称实参)
  • 方法的返回值:方法执行完成后,给方法的调用者返回的结果数据。

6.2 方法的声明和调用

洗衣机 方法
工厂生产洗衣机 声明方法
用户使用洗衣机 调用方法

6.2.1 声明方法的代码

// 声明一个方法:求两个整数的和
// int a,int b声明方法的参数:形式参数
// public int:表示方法的访问权限是public,返回值是int类型
// 方法名:add
public int add(int a, int b) {
    // 计算a + b的和
    int addResult = a + b;
    // 使用return关键字将a + b的和返回给方法的调用者
    return addResult;
}

6.2.2 调用方法的代码

// 1.要调用一个方法,需要先创建方法所在类的对象
Calculator calculator = new Calculator();
// 2.通过对象调用方法
// 这里传入给方法的5、11,我们叫做实际参数
int addResult = calculator.add(5, 11);

6.3 方法的相关规则

  • 方法调用一次就会执行一次
  • 方法必须写在类中不能独立存在
  • 方法如果没有返回值,方法体内可以没有return;如果写了return,那么表示方法结束
  • 方法声明的返回值类型必须和实际返回的数据类型一致
  • 方法内部不能再声明方法。

感谢尚硅谷老师的指导!!!

相关文章
|
6天前
|
安全 Java 编译器
Java对象一定分配在堆上吗?
本文探讨了Java对象的内存分配问题,重点介绍了JVM的逃逸分析技术及其优化策略。逃逸分析能判断对象是否会在作用域外被访问,从而决定对象是否需要分配到堆上。文章详细讲解了栈上分配、标量替换和同步消除三种优化策略,并通过示例代码说明了这些技术的应用场景。
Java对象一定分配在堆上吗?
|
3天前
|
存储 安全 Java
java.util的Collections类
Collections 类位于 java.util 包下,提供了许多有用的对象和方法,来简化java中集合的创建、处理和多线程管理。掌握此类将非常有助于提升开发效率和维护代码的简洁性,同时对于程序的稳定性和安全性有大有帮助。
28 17
|
4天前
|
存储 安全 Java
如何保证 Java 类文件的安全性?
Java类文件的安全性可以通过多种方式保障,如使用数字签名验证类文件的完整性和来源,利用安全管理器和安全策略限制类文件的权限,以及通过加密技术保护类文件在传输过程中的安全。
|
8天前
|
Java 数据格式 索引
使用 Java 字节码工具检查类文件完整性的原理是什么
Java字节码工具通过解析和分析类文件的字节码,检查其结构和内容是否符合Java虚拟机规范,确保类文件的完整性和合法性,防止恶意代码或损坏的类文件影响程序运行。
|
8天前
|
Java API Maven
如何使用 Java 字节码工具检查类文件的完整性
本文介绍如何利用Java字节码工具来检测类文件的完整性和有效性,确保类文件未被篡改或损坏,适用于开发和维护阶段的代码质量控制。
|
6天前
|
Java 关系型数据库 数据库
面向对象设计原则在Java中的实现与案例分析
【10月更文挑战第25天】本文通过Java语言的具体实现和案例分析,详细介绍了面向对象设计的五大核心原则:单一职责原则、开闭原则、里氏替换原则、接口隔离原则和依赖倒置原则。这些原则帮助开发者构建更加灵活、可维护和可扩展的系统,不仅适用于Java,也适用于其他面向对象编程语言。
8 2
|
8天前
|
存储 Java 编译器
java wrapper是什么类
【10月更文挑战第16天】
17 3
|
9天前
|
存储 缓存 NoSQL
一篇搞懂!Java对象序列化与反序列化的底层逻辑
本文介绍了Java中的序列化与反序列化,包括基本概念、应用场景、实现方式及注意事项。序列化是将对象转换为字节流,便于存储和传输;反序列化则是将字节流还原为对象。文中详细讲解了实现序列化的步骤,以及常见的反序列化失败原因和最佳实践。通过实例和代码示例,帮助读者更好地理解和应用这一重要技术。
7 0
|
9天前
|
监控 安全 Java
在 Java 中使用线程池监控以及动态调整线程池时需要注意什么?
【10月更文挑战第22天】在进行线程池的监控和动态调整时,要综合考虑多方面的因素,谨慎操作,以确保线程池能够高效、稳定地运行,满足业务的需求。
80 38
|
6天前
|
安全 Java
java 中 i++ 到底是否线程安全?
本文通过实例探讨了 `i++` 在多线程环境下的线程安全性问题。首先,使用 100 个线程分别执行 10000 次 `i++` 操作,发现最终结果小于预期的 1000000,证明 `i++` 是线程不安全的。接着,介绍了两种解决方法:使用 `synchronized` 关键字加锁和使用 `AtomicInteger` 类。其中,`AtomicInteger` 通过 `CAS` 操作实现了高效的线程安全。最后,通过分析字节码和源码,解释了 `i++` 为何线程不安全以及 `AtomicInteger` 如何保证线程安全。
java 中 i++ 到底是否线程安全?