第4章-面向对象编程(上)

news2024/11/15 8:07:59

1. 面向过程与面向对象

  • 面向过程
    在这里插入图片描述
  • 面向对象
    在这里插入图片描述

2. 面向对象的思想概述

  • 类(Class)和对象(Object)是面向对象的核心概念
    • 类是对一类事物的描述,是抽象的、概念上的定义
    • 对象是实际存在的该类事物的每个个体,因而也称为实例(instance)
    • 属性:对应类中的成员变量
    • 行为:对应类中的成员方法

2.1 类的语法格式

修饰符 class 类名 {
\qquad 属性声明;
\qquad 方法声明;
}

说明: 修饰符public:类可以被任意访问,类的正文要用{ }括起来。

在这里插入图片描述

在这里插入图片描述

2.2 对象的创建和使用

  • 创建对象语法: 类名 对象名 = new 类名();
  • 使用“对象名.对象成员”的方式访问对象成员(包括属性和方法)
    在这里插入图片描述

如果创建了一个类的多个对象,对于类中定义的属性,每个对象都拥有各自的一套副本,且互不干扰

在这里插入图片描述

  • 类的访问机制

    • 在一个类中的访问机制: 类中的方法可以直接访问类中的成员变量。(例外: static方法访问非static, 编译不通过。 )
    • 在不同类中的访问机制: 先创建要访问类的对象, 再用对象访问类中定义的成员
  • 对象的产生图解
    在这里插入图片描述

  • 对象的使用图解
    在这里插入图片描述

2.3 内存解析

在这里插入图片描述

  • 堆( Heap) , 此内存区域的唯一目的就是存放对象实例, 几乎所有的对象实例都在这里分配内存。 这一点在Java虚拟机规范中的描述是:所有的对象实例以及数组都要在堆上分配
  • 栈( Stack) , 是指虚拟机栈。 虚拟机栈用于存储局部变量等。局部变量表存放了编译期可知长度的各种基本数据类型( boolean、 byte、char 、 short 、 int 、 float 、 long 、double) 、 对象引用( reference类型,它不等同于对象本身, 是对象在堆内存的首地址) 。 方法执行完, 自动释放。
  • 方法区(Method Area) , 用于存储已被虚拟机加载的类信息、 常量、 静态变量、 即时编译器编译后的代码等数据。

2.4 匿名对象

  • 我们也可以不定义对象的句柄,而直接调用这个对象的方法。这样的对象叫做匿名对象。如: new Person().shout();
  • 使用情况
    • 如果对一个对象只需要进行一次方法调用,那么就可以使用匿名对象
    • 我们经常将匿名对象作为实参传递给一个方法调用

2.5 类的成员之一:属性(field)

  • 语法格式:
    • 修饰符 数据类型 属性名 = 初始化值 ;
  • 说明1: 修饰符
    • 常用的权限修饰符有: private、缺省、 protected、 public
    • 其他修饰符: static、 final (暂不考虑)
  • 说明2:数据类型
    • 任何基本数据类型(如int、 Boolean) 或 任何引用数据类型
  • 说明3:属性名
    • 属于标识符,符合命名规则和规范即可

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

2.6 类的成员之二:方法(method)

  • 什么是方法(method、函数)
    • 方法是类或对象行为特征的抽象,用来完成某个功能操作。在某些语言中也称为函数或过程
    • 将功能封装为方法的目的是,可以实现代码重用,简化代码
    • Java里的方法不能独立存在,所有的方法必须定义在类里
  • 方法的声明格式
    修饰符 返回值类型 方法名(参数类型 形参1, 参数类型 形参2, ….){
    \qquad 方法体程序代码
    \qquad return 返回值;

在这里插入图片描述

2.6.1 方法的重载

  • 重载的概念
    在同一个类中,允许存在一个以上的同名方法,只要它们的参数个数或者参数
    类型不同即可
  • 重载的特点
    与返回值类型无关,只看参数列表,且参数列表必须不同。 (参数个数或参数类
    型)。调用时, 根据方法参数列表的不同来区别
    不允许存在方法名相同,参数列表相同,返回值不同的两个方法
  • 重载示例
    • int add(int x,int y){return x+y;}
    • int add(int x,int y,int z){return x+y+z;}
    • double add(double x,double y){return x+y;}

2.6.2 可变形参的方法

在这里插入图片描述

  • 说明
    • 声明格式: 方法名(参数的类型名 …参数名)
    • 可变参数:方法参数部分指定类型的参数个数是可变多个: 0个, 1个或多个
    • 可变个数形参的方法与同名的方法之间,彼此构成重载
    • 可变参数方法的使用与方法参数部分使用数组是一致的
    • 方法的参数部分有可变形参,需要放在形参声明的最后
    • 在一个方法的形参位置,最多只能声明一个可变个数形参

2.6.3 方法参数的值传递机制

方法,必须由其所在类或对象调用才有意义。若方法含有参数

  • 形参:方法声明时的参数
  • 实参: 方法调用时实际传给形参的参数值

Java的实参值如何传入方法呢?
Java里方法的参数传递方式只有一种: 值传递。 即将实际参数值的副本(复制品)传入方法内,而参数本身不受影响

  • 形参是基本数据类型:将实参基本数据类型变量的“数据值”传递给形参
public class UntifaTest {
    public static void main(String[] args) {
        int x = 5;
        System.out.println("修改之前x = " + x);// 5
// x是实参
        change(x);
        System.out.println("修改之后x = " + x);// 5
    }

    public static void change(int x) {
        System.out.println("change:修改之前x = " + x);
        x = 3;
        System.out.println("change:修改之后x = " + x);
    }
}

在这里插入图片描述

  • 形参是引用数据类型:将实参引用数据类型变量的“地址值”传递给形参

  • 例子1

public class UntifaTest {
    public static void main(String[] args) {
        Person obj = new Person();
        obj.age = 5;
        System.out.println("修改之前age = " + obj.age);// 5
// x是实参
        change(obj);
        System.out.println("修改之后age = " + obj.age);// 3
    }

    public static void change(Person obj) {
        System.out.println("change:修改之前age = " + obj.age);
        obj.age = 3;
        System.out.println("change:修改之后age = " + obj.age);
    }

    static class Person {
        int age;
    }
}

结果:
在这里插入图片描述
内存图解析:
在这里插入图片描述

  • 例子2
public class UntifaTest {
    public static void main(String[] args) {
        Person obj = new Person();
        obj.age = 5;
        System.out.println("修改之前age = " + obj.age);// 5
// x是实参
        change(obj);
        System.out.println("修改之后age = " + obj.age);// 3
    }

    public static void change(Person obj) {
        obj = new Person();
        System.out.println("change:修改之前age = " + obj.age);
        obj.age = 3;
        System.out.println("change:修改之后age = " + obj.age);
    }

    static class Person {
        int age;
    }
}

结果:
在这里插入图片描述

内存图解析:
在这里插入图片描述

  • 例子3
public class UntifaTest {
    public static void main(String[] args) {
        UntifaTest test = new UntifaTest();
        int a = 5;
        int b = 10;
        test.swap(a, b);
        System.out.println("交换结束后,变量a的值是" + a + ";变量b的值是" + b);
    }

    public void swap(int a, int b) {
        int tmp = a;
        a = b;
        b = tmp;
        System.out.println("swap方法里, a的值是" + a + "; b的值是" + b);
    }
}

结果:
在这里插入图片描述
内存分析:略

  • 例子4
public class TransferTest2 {
    public static void swap(DataSwap ds) {
        int temp = ds.a;
        ds.a = ds.b;
        ds.b = temp;
        System.out.println("swap方法里, a Field的值是" + ds.a + ";b Field的值是" + ds.b);
    }

    static class DataSwap {
        public int a;
        public int b;
    }
}
public class UntifaTest {
    public static void main(String[] args) {
        TransferTest2.DataSwap ds = new TransferTest2.DataSwap();
        ds.a = 5;
        ds.b = 10;
        swap(ds);
        System.out.println("交换结束后, a Field的值是" + ds.a + ";b Field的值是" + ds.b);
    }
}

结果:
在这里插入图片描述

  • 例子5
public class TransferTest3 {
    public static void main(String args[]) {
        TransferTest3 test = new TransferTest3();
        test.first();
    }
    public void first() {
        int i = 5;
        Value v = new Value();
        v.i = 25;
        second(v, i);
        System.out.println(v.i);
    }
    public void second(Value v, int i) {
        i = 0;
        v.i = 20;
        Value val = new Value();
        v = val;
        System.out.println(v.i + " " + i);
    }

    static class Value {
        int i = 15;
    }
}

2.6.4 递归方法

一个方法体内调用它自身

  • 方法递归包含了一种隐式的循环,它会重复执行某段代码,但这种重复执行无须循环控制
  • 递归一定要向已知方向递归,否则这种递归就变成了无穷递归,类似于死循环
public class UntifaTest {
    private static int count = 0;

    public static void main(String[] args) {
        recursion(10);
    }

    public static int recursion(int k) {
        count++;
        System.out.println("Count: " + count + " k: " + k);
        if (k <= 0) {
            return 0;
        }
        return recursion(k - 1) + recursion(k - 2);
    }
}

结果:
在这里插入图片描述
思路:
在这里插入图片描述

2.7 封装与隐藏

中通过将数据声明为私有的(private), 再提供公共的( public)方法:getXxx()和setXxx()实现对该属性的操作, 以实现下述目的:

  • 隐藏一个类中不需要对外提供的实现细节
  • 使用者只能通过事先定制好的方法来访问数据, 可以方便地加入控制逻辑,限制对属性的不合理操作
  • 便于修改, 增强代码的可维护性
    在这里插入图片描述
    在这里插入图片描述

2.8 构造器

  • 构造器的特征

    • 它具有与类相同的名称
    • 它不声明返回值类型
    • 不能被static、 final、 synchronized、 abstract、 native修饰,不能有return语句返回值
  • 构造器的作用

    • 创建对象;给对象进行初始化
  • 语法格式
    \qquad 修饰符 类名 (参数列表) {
    \qquad 初始化语句;
    }

  • 根据参数不同,构造器可以分为如下两类

    • 隐式无参构造器(系统默认提供)
    • 显式定义一个或多个构造器(无参、有参)

注 意:
Java语言中,每个类都至少有一个构造器
默认构造器的修饰符与所属类的修饰符一致
一旦显式定义了构造器, 则系统不再提供默认构造器
一个类可以创建多个重载的构造器
父类的构造器不可被子类继承

  • 构造器重载
    • 构造器一般用来创建对象的同时初始化对象
    • 构造器重载,参数列表必须不同
    • 构造器重载使得对象的创建更加灵活,方便创建各种不同的对象
      例如:
      public class Person{
      \qquad public Person(String name, int age, Date d) {this(name,age);…}
      \qquad public Person(String name, int age) {…}
      \qquad public Person(String name, Date d) {…}
      \qquad public Person(){…}
      }

2.9 属性的赋值过程

截止到目前,我们讲到了很多位置都可以对类的属性赋值。现总结这几个位置,并指明赋值的先后顺序。

  • 赋值的位置
    • ① 默认初始化
    • ② 显式初始化 / ⑤在代码块中赋值
    • ③ 构造器中初始化
    • ④ 通过“对象.属性“或“对象.方法”的方式赋值
  • 赋值的先后顺序
    • ① - ② / ⑤ - ③ - ④
    • ②和⑤谁先谁后,那就看谁先写了

2.10 JavaBean及UML类图

  • JavaBean是一种Java语言写成的可重用组件
  • 所谓javaBean,是指符合如下标准的Java类:
    • 类是公共的
    • 有一个无参的公共的构造器
    • 有属性,且有对应的get、 set方法

在这里插入图片描述

2.11 this

  • 它在方法内部使用,即这个方法所属对象的引用

  • 它在构造器内部使用,表示该构造器正在初始化的对象

  • this 可以调用类的属性、方法和构造器

  • 什么时候使用this关键字呢

    • 当在方法内需要用到调用该方法的对象时,就用this
    • 我们可以用this来区分属性和局部变量,例如:this.name = name

在这里插入图片描述
在这里插入图片描述

注意:
\qquad 可以在类的构造器中使用"this(形参列表)"的方式,调用本类中重载的其他的构造器!
\qquad 明确:构造器中不能通过"this(形参列表)“的方式调用自身构造器
\qquad 如果一个类中声明了n个构造器,则最多有 n - 1个构造器中使用了"this(形参列表)”
\qquad "this(形参列表)"必须声明在类的构造器的首行!
\qquad 在类的一个构造器中,最多只能声明一个"this(形参列表)

2.12 package、import

  • package
    package语句作为Java源文件的第一条语句,指明该文件中定义的类所在的包。 (若缺省该语句,则指定为无名包)。
    它的格式为:package 顶层包名.子包名;

  • 包对应于文件系统的目录, package语句中,用 “.” 来指明包(目录)的层次;

  • 包通常用小写单词标识。通常使用所在公司域名的倒置: com.atguigu.xxx

  • import
    为使用定义在不同包中的Java类,需用import语句来引入指定包层次下所需要的类或全部类(.*)。 import语句告诉编译器到哪里去寻找类。
    语法格式:import 包名. 类名;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/739636.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Microsoft Remote Desktop for mac安装教程

适用于Mac的Microsoft远程桌面测试版&#xff01;Microsoft Remote Desktop Beta for Mac是一种远程工具&#xff0c;允许用户从Mac远程访问基于Windows的计算机。使用此工具&#xff0c;用户可以随时随地使用Mac连接到远程桌面、应用程序和资源。 Microsoft Remote Desktop B…

分享一下快速搭建IntelliJ IDEA开发环境的完整教程

目录 第一步&#xff1a;安装jdk&#xff0c;推荐安装jdk1.8 第二步&#xff1a;安装Maven 第三步&#xff1a;配置环境变量 1、jdk环境变量配置 2、maven环境变量配置 第四步&#xff1a;修改Maven仓库的地址 第五步&#xff1a;修改idea设置 IntelliJ IDEA是我们Java程…

云原生之深入解析K8S 1.24的高可用环境部署

一、Kubernetes 1.24 版本发布及重磅改动 2022 年 5 月 3 日&#xff0c;Kubernetes 1.24 正式发布&#xff0c;在新版本中&#xff0c;可以看到 Kubernetes 作为容器编排的事实标准&#xff0c;正愈发变得成熟&#xff0c;有 12 项功能都更新到了稳定版本&#xff0c;同时引入…

如何在windows上安装Openssl环境

首先在链接下载openssl安装版 openssl windows 我选择的是肥一点的版本 然后就是按向导步骤安装。 安装完后&#xff0c;首先要先设置下环境变量 我安装的路径是 C:\Program Files\OpenSSL-Win64\bin接下来&#xff0c;我以我的windows11为例说明&#xff0c; 在任务栏开始…

快使用双截棍 | 低码之数据模型 元服务开发的奇门武器

中国武术博大精深&#xff0c;刀枪棍棒层出不穷。从中国古代流传下来的一件奇门武器&#xff0c;软中带硬&#xff0c;柔中有钢&#xff0c;名叫双节棍&#xff0c;又名双截棍。双截棍短小精悍&#xff0c;携带方便&#xff0c;普通人也可以打出160斤以上的力道&#xff0c;威力…

【项目一】IO库对比、文件操作

文章目录 1.17 标准C库IO函数和Linux系统IO函数对比1.18 虚拟地址空间1.19 文件描述符1.20 open打开文件1.20 open创建文件1.22 read、write函数1.23 lseek函数1.24 stat、lstat函数1.25 使用stat函数模拟实现 ls -l 命令1.26 文件属性操作函数1.27 目录操作函数1.28 目录遍历函…

linux 乱码

在 Linux 中遇到乱码问题通常是由于字符编码不正确导致的。以下是几种常见的乱码情况以及相应的解决方法&#xff1a; 1、终端乱码&#xff1a;如果在终端中出现了乱码&#xff0c;可以尝试以下方法来解决&#xff1a; 检查终端的字符编码设置&#xff1a;确保终端的字符编码…

18 MFC TCP和UDP 网络通信

文章目录 TCP服务器TCP客户端UDP 服务器UDP客户端MFC TCP通信TCP服务器TCP 客户端 MFC UDP通信 TCP服务器 #include <stdio.h> #include <WinSock2.h> #pragma comment(lib,"ws2_32.lib") //包含静态库/* .obj .lib 文件 组合打包成 .exe */int main()…

申请和注销设备号的方法

一、Linux内核对设备的分类 linux的文件种类&#xff1a; -&#xff1a;普通文件 d&#xff1a;目录文件 p&#xff1a;管道文件 s&#xff1a;本地socket文件 l&#xff1a;链接文件 c&#xff1a;字符设备 b&#xff1a;块设备 Linux内核按驱动程序实现模型框架的不…

【C/C++练习】经典的排列组合问题(回溯算法)——电话号码的字母组合

&#x1f4d6;题目描述 题目出处&#xff1a;电话号码的字母组合 示例&#xff1a; &#x1f4d6;题解  这是一道典型的排列组合问题&#xff0c;根据输入&#xff0c;我们需要找到所有的组合。下面以输入字符串digits "23"为例来讲解这道题目。 图解&#xff1…

Java入门到入土(集合篇)

前言 初出茅庐 Collection集合特点 Map集合特点 牛刀小试 List集合用法 迭代器原理 Set集合用法 Map集合用法 追根溯源 List集合解析 Set集合解析 Map集合解析 结束语 前言 Java中用来批量存储数据的方式有…

mac 怎么批量修改文件后缀?

mac 批量修改文件后缀的方法教程~平时在电脑上使用文件的时候&#xff0c;经常需要对文件的后缀名进行修改&#xff0c;文件后缀名也就是文件扩展名&#xff0c;如果仅是单纯的修改文件后缀名&#xff0c;并不涉及格式转换的情况下&#xff0c;其实方法很简单&#xff0c;只需要…

ZBrush 3D游戏建模教程:创建女武士模型

推荐&#xff1a;将NSDT场景编辑器加入你的3D工具链 3D工具集&#xff1a;NSDT简石数字孪生 介绍 在本教程中&#xff0c;演示创建实时武士角色的流程&#xff0c;该流程基于 Kati Sarin S 的原始概念。我将使用各种各样的软件&#xff0c;如ZBrush&#xff0c;Maya&#xff…

微信小程序外卖管理的设计与实现(论文+源码)_kaic

摘要 随着互联网技术的不断更新和发展&#xff0c;人们的生活水平也在不断的提高&#xff0c;人们对互联网的依赖越来越紧密&#xff0c;尤其是网上外卖也越来越习惯了。它的功能包括在主页上列出出售的外卖。您也可以直接在首页顶部搜索想要的产品&#xff0c;如果余额不足&am…

信号与系统课程实验报告: 连续信号及其傅里叶变换的编程

一、实验目的 认识并熟悉Matlab软件的使用&#xff0c;并能利用其进行编程利用Matlab实现连续信号的表示掌握数值法和符号法进行编程实现连续周期信号的傅里叶级数求解编程算法实现连续信号的傅里叶变换求解编程算法理解Matlab代码的具体意义并熟练使用利用Matlab对LTI系统的频…

Maven依赖管理(核心)

依赖配置 依赖&#xff1a;指当前项目运行所需要的jar包&#xff0c;一个项目可以引入多个依赖配置&#xff1a; 在pom.xml中编写<dependencies>标签在<dependencies>标签中使用<dependency>引入坐标定义坐标的groupId、artifacId、version点击刷新按钮&…

二叉树层序遍历

目录 一、什么是层序遍历 二、层序遍历的实现 三、判断一棵树是否为完全二叉树 总结&#xff1a; 学习二叉树结构&#xff0c;最简单的就是遍历。 所谓二叉树遍历就是按照某种规则对二叉树中的节点进行相应操作&#xff0c;每个节点值操作一次。 遍历是二叉树的重要运算之…

深入篇【C++】手搓模拟实现string类(详细剖析常见的各接口):【400行代码实现】

深入篇【C】手搓模拟实现string类(包含常见的各接口&#xff09;&#xff1a;【400行代码实现】 【string类模拟实现完整代码】Ⅰ.构造/析构1.string()2.operator3.~string() Ⅱ.访问遍历1.operator[]2.iterator3.范围for Ⅲ.增操作1.push_back()2.append()3.operator4.insert(…

Harbor未授权创建管理员

人处在幸福与不幸交织的矛盾之中&#xff0c;反而使内心有一种更为深刻的痛苦&#xff0c;看来近在眼前的幸福而实际上又远得相当渺茫&#xff0c;海市蜃楼。放不得抓不住。 漏洞描述 近日&#xff0c;镜像仓库Harbor爆出任意管理员注册漏洞&#xff0c;攻击者在请求中构造特…

eNSP-VLAN多端口成员模式+DHCP

VLAN多端口成员模式DHCP 文章目录 VLAN多端口成员模式DHCP一、题目要求二、题目分析三、拓扑结构四、基本配置五、测试验证1.网段测试2.访问测试 一、题目要求 1、PC1和pc3所在接口为Access接口&#xff0c;PC2/4/5/6处于同一网段&#xff0c;其中PC2可以访问PC4/5/6&#xff…