Java 每日一刊(第12期):面向对象

news2024/11/13 9:29:29

“任何复杂的程序,都可以通过分解成若干个简单的问题来解决。”

前言

这里是分享 Java 相关内容的专刊,每日一更。

本期将为大家带来以下内容:

  1. 对象
  2. 类与对象的关系
  3. Java 中的三种变量类型
  4. OOP 的三大特性

是对现实世界中某类事物的抽象,它包含了描述这些事物的属性和行为。在 Java 中,类是通过 class 关键字定义的,通常包含 成员变量(属性)方法(行为)。类的成员变量用于表示对象的状态,而方法则用于描述对象的行为。

一个 Java 类的基本结构如下:

  • 类名:用来标识类。
  • 成员变量:用于存储对象的属性。
  • 方法:描述类的行为,完成某种功能。
// 类名:Car
public class Car {
    // 成员变量(属性)
    private String brand;

    // 方法(行为)
    public void accelerate(int increment) {
        speed += increment;
    }
}

对象

对象 是类的实例化。类是一个抽象的概念,只有通过创建对象才能具体使用类中的属性和方法。对象可以拥有不同的状态(成员变量的不同值),但它们都是基于同一个类。

创建对象

对象的创建通过 new 关键字完成,new 关键字会调用类的构造方法来生成对象实例。例如:

Car myCar = new Car();  // 创建一个 Car 类的对象

在这段代码中,myCarCar 类的一个对象。它是类的具体表现形式,可以调用类中的方法并访问其属性。

构造方法

构造方法 是在创建对象时自动调用的特殊方法,主要用于初始化对象的属性。构造方法的名字与类名相同,且没有返回类型。构造方法可以接收参数,用于对新创建对象的成员变量赋值。

构造方法的主要功能是初始化对象的成员变量,它的定义类似于普通方法,但无返回值。每次创建类的对象时,都会调用构造方法。

默认构造方法:如果类中没有显式定义构造方法,Java 会自动提供一个无参数的默认构造方法。

public class Car {
    private String brand;
    private int speed;
}
// 默认构造方法自动生成:public Car() {}

自定义构造方法:可以通过手动定义构造方法来对对象的初始状态进行设置。

public class Car {
    private String brand;
    private int speed;

    // 自定义构造方法
    public Car(String brand, int speed) {
        this.brand = brand;
        this.speed = speed;
    }
}

构造方法的作用是为对象提供初始化的值。在实例化对象时,构造方法会被自动调用

Car myCar = new Car("Toyota", 0);  // 调用自定义的构造方法

这里创建了一个 Car 对象 myCar,其品牌被初始化为 "Toyota",速度为 0

类与对象的关系

:定义了一类事物的共同特征和行为。它只是一种描述,类似于模板。

对象:是类的具体实例。每个对象都有自己的状态,并且可以调用类中的方法。

可以将类看作是一种类型,而对象就是这种类型的实例。例如,Car 类定义了汽车的行为和属性,而实际创建的 myCar 对象则是某一辆具体的车。

Java 中的三种变量类型

在 Java 中,根据变量的声明位置和生命周期,变量分为两大类:成员变量和局部变量。其中,成员变量可以进一步细分为 实例变量和类变量(静态变量)

成员变量

成员变量是定义在类中的变量,但位于方法、构造函数或代码块之外。它们用于描述类或对象的状态,可以被类中的方法或构造函数访问和修改。

根据是否使用 static 关键字修饰,成员变量分为两种:实例变量和类变量(静态变量)。

实例变量

实例变量是没有 static 修饰的成员变量,属于类的每一个具体对象。每个对象都有自己独立的实例变量,表示对象的个体状态。

特点:

  • 归属于对象:每个对象都有自己的一份实例变量副本,多个对象之间互不影响。
  • 初始化:实例变量在对象创建时自动初始化。如果没有显式赋值,Java 会为实例变量赋予默认值(如 int 的默认值是 0,对象引用类型的默认值是 null)。
  • 生命周期:实例变量的生命周期从对象创建开始,到对象销毁为止。
  • 作用范围:实例变量可以在类的所有非静态方法中使用,并且通过对象进行访问。
public class Person {
    // 实例变量:每个 Person 对象有独立的 name 和 age
    private String name;
    private int age;

    // 构造方法
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public void displayInfo() {
        System.out.println("姓名: " + name + ", 年龄: " + age);
    }
}

nameage 是实例变量,属于 Person 对象。每个 Person 对象都有自己独立的 nameage 值。

Person person1 = new Person("张三", 25);
Person person2 = new Person("李四", 30);

person1.displayInfo();  // 输出: 姓名: 张三, 年龄: 25
person2.displayInfo();  // 输出: 姓名: 李四, 年龄: 30

在上面代码中,person1person2 是两个不同的对象,它们的实例变量 nameage 是独立的,互不影响。

类变量(静态变量)

类变量,也叫静态变量,是使用 static 关键字修饰的 成员变量。类变量属于整个类而不是某个具体的对象,因此所有对象共享同一个类变量。

类变量是在类中使用 static 关键字定义的成员变量。它们存储在类的静态内存区域中,并且只有一份存储空间,不随对象的创建而变化。

特点:

  • 归属于类:类变量属于类本身,而不是某个对象,所有实例共享这一个变量。
  • 初始化:类变量在类加载时初始化,只会初始化一次,且所有对象共享同一个值。
  • 生命周期:类变量的生命周期与类的生命周期相同,从类加载到类卸载期间存在。
  • 访问方式:类变量可以通过类名直接访问,也可以通过对象访问(但不推荐)。推荐通过类名访问以突出它与对象无关。
public class Employee {
    // 类变量
    public static int employeeCount = 0;  // 记录员工数量

    // 构造方法
    public Employee() {
        employeeCount++;  // 每创建一个 Employee 对象,数量加1
    }
}

employeeCount 是一个类变量,属于 Employee 类。所有 Employee 对象共享这个变量,每次创建一个新的 Employee 对象时,employeeCount 的值都会增加。

类变量可以通过类名直接访问,也可以通过对象访问(但通常不推荐)。

Employee emp1 = new Employee();
Employee emp2 = new Employee();

System.out.println(Employee.employeeCount);  // 输出: 2

在这个示例中,无论我们创建多少个 Employee 对象,employeeCount 变量始终是共享的。当我们创建两个 Employee 对象后,employeeCount 的值变为 2,可以通过类名 Employee 来访问该变量。

局部变量

局部变量是定义在方法、构造函数或代码块中的变量,它们仅在其所在的代码块内有效,作用范围较小且生命周期较短。

特点:

  • 定义位置:局部变量在方法、构造函数或代码块内部声明,通常用于存储临时数据。
  • 作用范围:局部变量的作用范围仅限于方法或代码块,不能被类中的其他方法或代码块访问。
  • 初始化:局部变量必须在使用前显式初始化,否则会出现编译错误。
  • 生命周期:局部变量的生命周期是从方法或代码块执行时开始,到方法或代码块结束时销毁。
public void calculateSum() {
    int a = 10;  // 局部变量
    int b = 20;  // 局部变量
    int sum = a + b;
    System.out.println("和: " + sum);
}

calculateSum 方法中,absum 都是局部变量,它们只能在这个方法中使用,方法执行完毕后这些变量会被销毁,无法在其他地方使用。

public class Example {
    // 成员变量
    private int memberVar = 10;

    public void showDifference() {
        // 局部变量
        int localVar = 5;
        System.out.println("成员变量: " + memberVar);
        System.out.println("局部变量: " + localVar);
    }
}

在上述代码中,memberVar 是类的成员变量,它可以在整个类的非静态方法中使用,而 localVar 是局部变量,只能在 showDifference 方法内部使用,方法执行完后即销毁。

三种变量类型的对比

比较点成员变量(实例变量)类变量(静态变量)局部变量
归属属于对象属于类属于方法
初始化默认值有默认值有默认值必须显式初始化
生命周期对象存在时存在,随对象销毁随类加载和卸载方法执行期间存在,随方法结束而销毁
作用域整个类内部都可以访问整个类内部都可以访问,且类的所有实例共享仅在定义的代码块或方法内部有效
访问方式通过对象访问通过类名或对象访问不能在方法外部访问

OOP 的三大特性

Java 是一种面向对象编程(OOP)的语言,OOP 的常说的三大特性包括 封装、继承、多态。这些特性帮助开发者以更结构化和模块化的方式构建软件系统。下面将详细解释每一个特性。

封装(Encapsulation)

封装是面向对象编程的一个核心概念,它通过将对象的状态(属性)和行为(方法)隐藏起来,并提供公共的方法来访问它们。封装的目标是将对象的内部实现细节对外部隐藏,仅通过公开的接口与外界交互,从而保护对象的完整性,避免外部对对象内部状态的非法访问或不当修改。

访问修饰符控制访问权限

在 Java 中,封装通常通过访问修饰符来实现。Java 提供了四种访问修饰符,分别是:

修饰符含义
private只能在当前类中访问
default(没有修饰符)只能在同一包中访问
protected可以在同一包中或继承该类的子类中访问
public可以在任何地方访问

继承(Inheritance)

继承是 OOP 中用于重用代码的一种机制,通过继承,一个类可以继承另一个类的属性和方法,从而使子类拥有父类的功能。继承使得代码的复用性和可扩展性得到了提升。

子类与父类的关系

在继承中,已有的类被称为父类(superclass)或基类(base class),继承该类的类被称为子类(subclass)。子类不仅可以使用父类中已有的属性和方法,还可以添加自己的属性和方法,或者对父类的方法进行重写。

class Animal {
    public void eat() {
        System.out.println("Animal is eating");
    }
}

class Dog extends Animal {
    public void bark() {
        System.out.println("Dog is barking");
    }
}

在上面的例子中,Dog 类继承了 Animal 类,并且拥有了 Animal 类的 eat 方法。

继承的好处与弊端

好处:

  • 代码重用:子类可以直接复用父类中的代码,不需要重复编写相同的代码。
  • 扩展性:子类可以在父类的基础上添加新的功能,增强了系统的可扩展性。

弊端:

  • 耦合性:子类与父类之间存在较强的耦合,如果父类的实现发生变化,可能会影响所有继承它的子类。
  • 继承层次复杂:多层继承会导致代码结构复杂,维护成本增加。

多态(Polymorphism)

多态是指同一个方法在不同对象上具有不同的行为。Java 中的多态分为两种:

  • 编译时多态(通过方法重载实现)
  • 运行时多态(通过方法重写和动态绑定实现)。
方法重载(Overloading)

在同一个类中,多个方法拥有相同的名字,但参数列表不同(参数的类型或数量不同),这就是方法重载。重载是编译时多态的表现。

public class Calculator {
    public int add(int a, int b) {
        return a + b;
    }

    public double add(double a, double b) {
        return a + b;
    }
}
方法重写(Overriding)

子类重写父类的方法,提供自己的实现版本,这就是方法重写。重写是运行时多态的表现。

class Animal {
    public void sound() {
        System.out.println("Animal makes sound");
    }
}

class Dog extends Animal {
    @Override
    public void sound() {
        System.out.println("Dog barks");
    }
}
运行时多态和编译时多态

编译时多态(Compile-time Polymorphism):通过方法重载实现,方法的调用在编译时决定。

运行时多态(Runtime Polymorphism):通过方法重写和动态绑定实现,在运行时根据对象的实际类型来决定调用哪个方法。

Animal animal = new Dog();
animal.sound(); // 输出 "Dog barks"

在这个例子中,虽然编译时 animal 被声明为 Animal 类型,但在运行时实际是 Dog 对象,因此调用的是 Dog 类的 sound 方法。

本期小知识

多态 (Polymorphism) 是面向对象编程的核心概念之一。Java 中有两种绑定方式:静态绑定 (Static Binding) 和动态绑定 (Dynamic Binding)。

静态绑定:在编译时确定调用的方法。这通常用于静态方法、私有方法或 final 方法。

动态绑定:在运行时确定调用的方法。这用于实例方法的调用,Java 默认会基于对象的实际类型调用对应的方法。

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

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

相关文章

修改Docker默认存储路径,解决系统盘占用90%+问题(修改docker root dir)

随着Docker技术的广泛应用,它极大地简化了复杂项目的部署与维护流程,仅凭单一镜像即可轻松运行。然而,随着数据量不断增长,Docker的默认数据存储方式可能逐渐成为挑战,尤其是当默认安装于根目录(“/”&…

计算机的错误计算(九十八)

摘要 探讨 的计算精度问题。 由计算机的错误计算(九十六)知,IEEE 754-2019标准中含有 运算。 另外,似乎没有语言直接编程实现内置了该运算。 例1. 已知 x-0.9999999999321 . 计算 不妨用Java编程计算: import…

微服务注册中⼼1

1. 微服务的注册中⼼ 注册中⼼可以说是微服务架构中的”通讯录“ ,它记录了服务和服务地址的映射关系。在分布式架构中, 服务会注册到这⾥,当服务需要调⽤其它服务时,就这⾥找到服务的地址,进⾏调⽤。 1.1 注册中⼼的…

前端面试题——token安全问题处理与大数据列表展示

1.长时间保存token问题 长时间保存Token涉及多个方面的问题,包括安全性、性能、以及Token的管理策略等。以下是对长时间保存Token问题的详细分析: 一、安全性问题 Token泄露风险: Token是用户身份验证的凭证,如果长时间保存且未…

矿场工程车检测数据集 4900张 工程车 带标注voc yolo

矿场工程车检测数据集 数据集描述 该数据集旨在用于矿场工程车的检测和分类任务,涵盖了多种常见的工程车辆类型。数据集包含了大量的工程车图像及其对应的标注信息,可用于训练计算机视觉模型,以识别和定位矿场中的不同工程车辆。 数据规模 …

【速成Redis】02 Redis 五大基本数据类型常用命令

前言: 上一节课,我们对redis进行了初步了解,和安装好了redis。【速成Redis】01 Redis简介及windows上如何安装redishttps://blog.csdn.net/weixin_71246590/article/details/142319358?spm1001.2014.3001.5501 该篇博客,我们正…

如何在Unity发布安卓移动端游戏

在移动端手机游戏开发的时候,我从最开始就遇到了一个问题,并不是技术上的问题,而是移动端游戏如何进行发布的问题,由于之前所使用的都是基于Windows平台的电脑游戏,并没有使用过手机游戏开发环境,所以&…

【ComfyUI】自定义节点ComfyUI_LayerStyle——模仿 Adob​​e Photoshop 的图层样式、图层混合、图文混合、添加不可见水印

官方代码:https://github.com/chflame163/ComfyUI_LayerStyle.git 相关资料下载:https://pan.baidu.com/s/16vmPe6-bycHKIjSapOAnZA?pwd0919 简介 在ComfyUI画布点击右键 - Add Node, 找到 “😺dzNodes”。 节点根据功能分为5组&#xff…

C++ | Leetcode C++题解之第403题青蛙过河

题目&#xff1a; 题解&#xff1a; class Solution { public:bool canCross(vector<int>& stones) {int n stones.size();vector<vector<int>> dp(n, vector<int>(n));dp[0][0] true;for (int i 1; i < n; i) {if (stones[i] - stones[i -…

【tomcat】tomcat学习笔记

文章目录 1.tomcat乱码问题1.1 linux乱码中文显示乱码问号问题1.2windows乱码1.2.1 方式一1.2.2方式二 1.3 Idea中运行tomcat乱码问题 2. 获取tomcat启动端口号3. idea运行tomcat 的配置问题4.dockerfile构建tomcat镜像问题4.1 替换端口号 5.启动多个tomcat方法6.修改tomcat JA…

Unity 设计模式 之 【什么是设计模式】/ 【为什么要使用设计模式】/ 【架构和设计模式的区别】

Unity 设计模式 之 【什么是设计模式】/ 【为什么要使用设计模式】/ 【架构和设计模式的区别】 目录 Unity 设计模式 之 【什么是设计模式】/ 【为什么要使用设计模式】/ 【架构和设计模式的区别】 一、简单介绍 二、 Unity 设计模式 1、Unity 开发中使用设计模式的特点 2…

LabVIEW软件维护的内容是什么呢?

LabVIEW软件维护涉及多个方面&#xff0c;确保程序的正常运行和长期稳定性。维护内容包括以下几个方面&#xff1a; 1. Bug修复 在开发和运行过程中&#xff0c;可能会出现各种软件问题或缺陷&#xff08;bugs&#xff09;。维护工作之一就是识别这些问题并通过修复程序中的代…

MATLAB 在数学建模中的深入应用:从基础到高级实践

目录 前言 一、MATLAB基础知识 1.1 MATLAB工作环境简介 1.1.1 命令窗口&#xff08;Command Window&#xff09; 1.1.2 工作区&#xff08;Workspace&#xff09; 1.1.3 命令历史&#xff08;Command History&#xff09; 1.1.4 编辑器&#xff08;Editor&#xff09; 1…

独立站冷启动SOP之市场和竞品调研1.0丨出海笔记

大家好&#xff0c;我是出海笔记Club的创始人Alan&#xff0c;过去半年我们做了15期的操盘手面对面&#xff0c;主要围绕的是跨境电商独立站的冷启动&#xff0c;基本上大部分方法和路径我们都覆盖到了。 我把目的&#xff0c;调研内容和可以使用的工具都罗列出来&#xff0c;…

Golang | Leetcode Golang题解之第417题太平洋大西洋水流问题

题目&#xff1a; 题解&#xff1a; type pair struct{ x, y int } var dirs []pair{{-1, 0}, {1, 0}, {0, -1}, {0, 1}}func pacificAtlantic(heights [][]int) (ans [][]int) {m, n : len(heights), len(heights[0])pacific : make([][]bool, m)atlantic : make([][]bool, …

如何使用 maxwell 同步到 redis?

文章目录 1、MaxwellListener2、MxwObject1. 使用Maxwell捕获MySQL变更2. 将Maxwell的输出连接到消息系统3. 从消息系统读取数据并同步到Redis注意事项 1、MaxwellListener package com.atguigu.tingshu.album.listener;import com.alibaba.fastjson.JSON; import org.apache.…

【RabbitMQ】重试机制、TTL

重试机制 在消息从Broker到消费者的传递过程中&#xff0c;可能会遇到各种问题&#xff0c;如网络故障、服务不可用、资源不足等&#xff0c;这些问题都可能导致消息处理失败。为了解决这些问题&#xff0c;RabbitMQ提供了重试机制&#xff0c;允许消息在处理失败之后重新发送…

汇编语言的基本指令及基本使用操作

一、立即数 立即数判断规则&#xff1a; 如果某个数的数值范围是0~255之间&#xff0c;那么这个数一定是立即数&#xff1b; 把某个数展开成2进制&#xff0c;这个数的最高位1至最低位1之间的二进制数序列的位数不能超过8位&#xff1b; 这个数的二进制序列的右边必须为偶数个…

Java-Day02学习

Java-Day02 一维数组 1.声明数组 int[ ] a; //声明数组时不规定数组长度 2.分配空间 a new int[5]; //分配空间: 告诉计算机分配几个连续的空间。eg:scores new int[30]; avgAge new int[6]; name new String[30]; 3.赋值 a [0] 8; //向分配的格子里放数…

结构体易忘点

结构体初始化 当我们去初始化一个结构体的时候&#xff0c;我们常常会按变量顺序初始化&#xff0c;但其实也可以不按顺序&#xff0c;同时也可以部分数据初始化。 结构体对齐 结构体里面的成员有一定的对齐规则&#xff0c;他不是每一个空间都存着有效数据的&#xff0c;有些…