《Java核心技术 卷I》第4章 对象与类

news2024/12/23 5:50:31

第4章 对象与类

面向对象程序设计(Object-Oriented Programming,OOP)。

实现一个简单的Web浏览器可能2000个过程,采用面向对象设计风格大约100个类,每个类平均包含20个方法。

(class)是构造对象的模板或蓝图,我们可以将类想象成制作小甜饼的切割机,将对象想象称为小甜饼。

由类构造器(construct)对象的过程称为创建类的实例(instance)。

封装(encapsulation,有时称为数据隐藏)是与对象有关的一个重要概念,将数据和行为组合在一个包中,并对对象使用者隐藏了数据的实现方式。对象中数据称为实例域(instance field),操纵数据的过程称为方法(method)。对于每个特定的类实例(对象)都有一组特定的实例域值,这些值的集合就是这个对象的当前状态(state)。无论何时,只要向对象发送一个消息,他的状态就有可能发生改变。

实现封装的关键在于绝对不能让类中的方法直接地访问其他类的实例域。程序仅通过对象的方法与对象数据进行交互。封装给对象赋予了黑盒特征,这是提高重用性和可靠性的关键。

通过拓展一个类来建立另外一个类的过程称为继承(inheritance)。

对象

对象三个主要特性:

  • 对象的行为(behavior):可以对对象施加哪些操作或方法?
  • 对象的状态(state):当施加这些方法时,对象如何响应?
  • 对象标识(identity):如何辨别具有相同行为与状态的不同对象?

每个对象都有一个唯一的身份(identity)。例如订单系统中,即使两个商品都一样,订单号也要不同。

识别类

传统过程化程序设计必须从顶部的main函数开始编写程序。面向对象则没有所谓的顶部。

对于OOP初学者会感到无从下手,答案是:首先从设计类开始,然后再往每个类中添加方法。

识别类的简单规则是在分析问题的过程中寻找名词,而方法对应着动词。

例如:订单处理系统中有这些名词

  • 项目(Item)
  • 订单(Order)
  • 送货地址(Shipping address)
  • 付款(Payment)
  • 账户(Account)

这些名词可能成为类Item,Order等。

接下来查看动词,项目被添加到订单中,订单被发送或取消,订单货款被支付,对于每一个动词,添加,发送,取消以及支付都要标识处主要负责完成的相应动作的对象。

类之间的关系

  • 依赖(uses-a)
  • 聚合(has-a)
  • 继承(is-a)

依赖(dependence),一个类的方法操纵另一个类的对象,我们就说一个类依赖于另一个类。Order类使用Account类,订单要操作账户,应该尽可能将相互依赖的类减至最少,让类之间的耦合度最小。

聚合(aggregation),是一种具体且易于理解的关系,例如Order对象包含了一些Item对象,聚合关系意味着类A的对象包含类B的对象。

继承(inheritance),表示特殊与一般的关系。

表示类关系的UML(Unified Modeling Language,统一建模语言)符号:

对象与对象变量

Java的日期类库有些混乱,重新设计参看:http://jcp.org/en/jsr/detail?id=310

一定要认识到:一个对象变量并没有实际包含一个对象,而仅仅引用一个对象。

在Java中,任何对象变量的值都是对存储在另外一个地方的对象的引用。new操作符的返回值也是一个引用。

可以将Java对象变量看做C++的对象指针。

所有的Java对象都存在堆中,当一个对象包含另一个对象变量时,这个变量依然包含着指向另一个堆对象的指针。

Date类中,有一个毫秒数时1970年1月1日开始。

日历表示法用GregorianCalendar类。格里高利历

案例:打印当前月的日历

未完待续。。。

用户自定义类

开始学习如何设计主力类(workhorse class)。这些类没有main方法,却又自己的实例域和实例方法。

要想创建一个完整的程序,其中只有一个类main方法。

Employee类

编写薪金管理时可能会用到,创建EmployeeTest类

package corejava;

import java.util.Date;
import java.util.GregorianCalendar;

public class EmployeeTest {

    public static void main(String[] args) {
        
        Employee[] staff = new Employee[3];
        staff[0] = new Employee("孙悟空", 75000,1987,12,15);
        staff[1] = new Employee("通背猿猴", 50000,1989,10,1);
        staff[2] = new Employee("赤尻马猴", 40000,1990,3,15);
        //涨工资5%
        for (Employee e : staff) {
            e.raiseSalary(5);
        }
        //打印信息
        for (Employee e : staff) {
            System.out.println("name="+e.getName()+",salary="+e.getSalary()+",hireDay="+e.getHireDay());
        }
    }

}
class Employee {
    //实例字段
    private String name;
    private double salary;
    private Date hireDay;
    //构造器
    public Employee(String n,double s,int year,int month, int day) {
        name = n;
        salary = s;
        GregorianCalendar calendar = new GregorianCalendar(year,month-1,day);
        hireDay = calendar.getTime();
    }
    public Employee() {}
    //
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public double getSalary() {
        return salary;
    }
    public void setSalary(double salary) {
        this.salary = salary;
    }
    public Date getHireDay() {
        return hireDay;
    }
    public void setHireDay(Date hireDay) {
        this.hireDay = hireDay;
    }
    public void raiseSalary(double byPercent) {
        double raise = salary * byPercent /100;
        salary += raise;
    }
}
//输出
//name=孙悟空,salary=78750.0,hireDay=Tue Dec 15 00:00:00 CST 1987
//name=通背猿猴,salary=52500.0,hireDay=Sun Oct 01 00:00:00 CST 1989
//name=赤尻马猴,salary=42000.0,hireDay=Thu Mar 15 00:00:00 CST 1990

注释:可以用public标记实例域,但是极为不提倡,任何方法都可以修改public的域,破坏了封装,强烈建议标记为private。

构造器伴随着new操作一起调用,不要在构造器里定义与域重名的局部变量。

在每一个方法中,关键字this表示隐式参数。

如果需要返回一个可变对象的引用,应该首先对它进行克隆(clone)。对象clone是指存放在另一个位置上的对象副本。

静态域

将域定义为static,每个类中只有一个这样的域,每个对象对于所有的实例域都有自己的一份拷贝。

1000个Employee类就有1000个实例域id,静态域nextId(静态变量)只有一个,所有对象共享。

静态常量

静态常量用的比较多,也是java中表示常量的方法。Math.PI.

静态方法

静态方法不能操作对象,不能在静态中访问实例域,可以访问自身类中的静态域。静态方法调用静态变量。类名直接调。

解释为:属于类且不属于类对象的变量和函数。

方法参数

按值调用(call by value)表示方法接收的是调用者提供的值。

按引用调用(call by reference)表示方法接收的是调用者提供的变量地址。

Java程序设计语言总是采用按值调用,也就是说方法得到的是所有参数值的一个拷贝,特别是,方法不能修改传递给它的任何参数变量的内容。

  • 一个方法不可能修改一个基本数据类型的参数,基本数据类型(数字,布尔)。
  • 一个方法可以改变一个对象参数的状态。
  • 一个方法不能让对象参数引用一个新的对象。

重载

如果多个方法有相同的名字,不同的参数,便是重载(overloading)。

完整描述一个方法,指出方法名以及参数类型,叫做方法的签名(signature)。

参数名

可以在每个参数前面加上一个前缀"a":

public Employee(String aName,double aSalary){...}

调用另一个构造器

有参构造器调用其他构造器,用this(nextId,s);

对象析构与finalize方法

Java不支持析构器,使用了内存之外的资源,可以为任何一个类添加finalize方法。

此方法将在垃圾回收器清除对象之前调用,实际应用中不要依赖于此方法回收任何短缺的资源,很难知道什么时候调用。

注释:System.runFinalizersOnExit(true)可以确保finalizer方法在Java关闭前被调用,但不安全,不鼓励大家使用。

替代方法是Runtime.addShutdownHook添加关闭钩(shutdown hook)。

sun公司建议将公司的因特网域名(独一无二)以逆序的形式作为包名,并且对于不同项目使用不同的子包。

com.clgao

静态导入

import static java.lang.System.*;

out.println("hello,world!")

exit(0);

例如:sqrt(pow(x,2)+pow(y,2))比Math点来点去清晰的多。

设置类路径

java -classpath c:\classdir;.;c:\archives\archive.jar MyProg

shell

export CLASSPATH=/....

Windows shell

set CLASSPATH=c:\......

注释

方法注释:

  • @param 变量描述,对参数添加一个条目,描述可多行
  • @return 描述,返回值进行描述
  • @throws类描述,异常描述

通用注释:

  • @author 姓名,多个作者
  • @version 文本,某个版本
  • @since 文本,始于某个时间或版本
  • @deprecated 文本,不在使用,给出取代的建议
  • @see 引用,增加一个超链接
  • @link 引用,类似于see

注释的抽取,javadoc -d 目录

类设计技巧

  • 一定要保证数据私有
  • 一定要对数据初始化
  • 不要在类中使用过多的基本类型
  • 不是所有的域都需要独立的域访问器和域更改器
  • 将职责过多的类进行分解
  • 类名和方法名要能够体现它们的职责

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

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

相关文章

【JavaScript】axios 二次封装拦截器(接口、实例、全局)

学习 coderwhy 老师结合 ts 二次封装 axios 目录结构 config config\index.ts // export const BASE_URL "http://codercba.com:9002"; export const TIME_OUT 10000;// 1. 根据环境变量区分接口地址 // let BASE_URL: string; // if (process.env.NODE_ENV &qu…

c++:vector模拟实现

一、vector成员变量 库里实现用的就是这三个成员变量&#xff0c;咱们实现跟库里一样&#xff0c; namespace myvector {template<class T>class vector{public://vecttor的迭代器是原生指针typedef T* iterator;typedef const T* const_iterator; private:iterator _sta…

数字后端零基础入门系列 | Innovus零基础LAB学习Day8

###LAB15 Detail Routing for Signal Integrity, Timing, Power and Design for Yield 这个章节虽然标题有点长&#xff0c;但不要被它吓到&#xff0c;其实这个章节就是Innovus工具的绕线Routing。只不过这个阶段做Route不是仅仅是把所有的逻辑连接&#xff0c;用实际的金属层…

发现研究的组织是自己所在组织,有点慌

donnyhuang 2019-5-29 23:34 我们做业务建模研究的组织可以是自己所在的组织吗&#xff1f;例如&#xff0c;如果我想做一个组件来来提高研发效能&#xff0c;那我研究的组织是我们部门的研发线可以吗&#xff1f; 因为最近做一个设备管理的建模&#xff0c;发现研究的组织是自…

将数学学生搞糊涂的糊涂话:面积(路程)是一种对应规则(关系)

黄小宁 将一种关系与构成此关系的成员、要素混为一谈是非常低级的常识性错误。问题是学生们做梦都不敢怀疑课本会有这样的错误。有战士与班长之间构成一种上下级关系&#xff0c;战士必须服从上级的指挥。将构成此关系中的班长说成是关系本身显然是概念性错误。同样&#xff0c…

(九)JavaWeb后端开发3——Servlet

目录 1.Servlet由来 2.Servlet快速入门 3.Servlet执行原理 4.Servlet生命周期 1.Servlet由来 在JaveEE API文档中对Servlet的描述是&#xff1a;可以运行在服务器端的微小程序&#xff0c;但是实际上&#xff0c;Servlet就是一个接口&#xff0c;定义了Java类被浏览器访问…

【51单片机】矩阵键盘

学习使用的开发板&#xff1a;STC89C52RC/LE52RC 编程软件&#xff1a;Keil5 烧录软件&#xff1a;stc-isp 开发板实图&#xff1a; 文章目录 矩阵键盘 矩阵键盘 矩阵键盘位于开发板的右下角 在键盘中按键数量较多时&#xff0c;为了减少I/O口的占用&#xff0c;通常将按键…

特朗普概念股分析:DJT和Phunware股价大涨:买还是卖?

猛兽财经核心观点&#xff1a; &#xff08;1&#xff09;特朗普媒体科技集团的股价已经从9月份的低点上涨了280%。 &#xff08;2&#xff09;随着特朗普赢得大选的概率上升&#xff0c;Phunware的股价也在大幅上涨 &#xff08;3&#xff09;这些股票在大选后逆转的可能性越来…

Python | Leetcode Python题解之第522题最长特殊序列II

题目&#xff1a; 题解&#xff1a; class Solution:def findLUSlength(self, strs: List[str]) -> int:def is_subseq(s: str, t: str) -> bool:pt_s pt_t 0while pt_s < len(s) and pt_t < len(t):if s[pt_s] t[pt_t]:pt_s 1pt_t 1return pt_s len(s)ans …

FlinkCDC-MYSQL批量写入

一、运行环境 &#xff08;1&#xff09;Flink&#xff1a;1.17.2 &#xff08;2&#xff09;Scala&#xff1a;2.12.20 &#xff08;3&#xff09;Mysql&#xff1a;5.7.43 ##开启binlog 二、代码示例 思路&#xff1a;通过滚动窗口收集一批数据推给sink消费。binlog日志对…

群控系统服务端开发模式-应用开发-上传配置功能开发

下面直接进入上传配置功能开发&#xff0c;废话不多说。 一、创建表 1、语句 CREATE TABLE cluster_control.nc_param_upload (id int(11) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT 编号,upload_type tinyint(1) UNSIGNED NOT NULL COMMENT 上传类型 1&#xff1a;本站 2&a…

【大语言模型】ACL2024论文-03 MAGE: 现实环境下机器生成文本检测

【大语言模型】ACL2024论文-03 MAGE: 现实环境下机器生成文本检测 目录 文章目录 【大语言模型】ACL2024论文-03 MAGE: 现实环境下机器生成文本检测目录摘要研究背景问题与挑战如何解决核心创新点算法模型实验效果&#xff08;包含重要数据与结论&#xff09;主要参考工作后续优…

C++设计模式结构型模式———组合模式

文章目录 一、引言二、组合模式三、总结 一、引言 组合模式是一种结构型设计模式&#xff0c; 可以使用它将对象组合成树状结构&#xff0c; 并且能像使用独立对象一样使用它们。代码实现中涉及了递归调用。组合模式与传统上的“类与类之间的组合关系”没有关联&#xff0c;不…

【C/C++】qsort函数的学习与使用

零.导言 在之前的文章中&#xff0c;我介绍了冒泡排序&#xff0c;即按ASCII码值把元素从小到大排序&#xff08;文章链接我放在了第五部分&#xff0c;有兴趣的小伙伴可以求看看&#xff09;。而今天我将继续介绍qsort函数&#xff0c;这个函数可以起到和冒泡排序一样的作用&a…

前段(vue)

目录 跨域是什么&#xff1f; SprinBoot跨域的三种解决方法 JavaScript 有 8 种数据类型&#xff0c; 金额的用什么类型。 前段 区别 JQuery使用$.ajax()实现异步请求 Vue 父子组件间的三种通信方式 Vue2 和 Vue3 存在多方面的区别。 跨域是什么&#xff1f; 跨域是指…

【elkb】索引生命周期管理

索引生命周期管理 Index lifecycle management(索引生命周期管理)是elasticsearch提供的一种用于自动管理索引的生命周期的功能。允许使用者定义索引的各个阶段&#xff0c;从创建至删除。并允许使用者在每个阶段定义索引需要执行的特定动作。这些动作包含索引创建&#xff0c…

基于SSM志愿者招募系统的设计

管理员账户功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;用户管理&#xff0c;志愿组织管理&#xff0c;组织信息管理&#xff0c;组织申请管理&#xff0c;志愿活动管理活动报名管理 用户账号功能包括&#xff1a;系统首页&#xff0c;个人中心&#xff0c;…

msys2更换国内源(多个文件(不是3个文件的版本!))

msys2更换国内源 起因排查答案如下mirrorlist.mingw64mirrorlist.ucrt64mirrorlist.mingw32mirrorlist.mingwmirrorlist.clang64mirrorlist.clang32mirrorlist.msys 不想看经过的直接跳到答案 起因 查了很多个教程大部分都是【打开MSYS2软件内的\etc\pacman.d\ 中3个文件&…

Spring Boot框架下的信息学科平台系统架构设计

3系统分析 3.1可行性分析 通过对本基于保密信息学科平台系统实行的目的初步调查和分析&#xff0c;提出可行性方案并对其一一进行论证。我们在这里主要从技术可行性、经济可行性、操作可行性等方面进行分析。 3.1.1技术可行性 本基于保密信息学科平台系统采用Spring Boot框架&a…

基于Python可视化的热门微博数据分析系统

作者&#xff1a;计算机学姐 开发技术&#xff1a;SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等&#xff0c;“文末源码”。 专栏推荐&#xff1a;前后端分离项目源码、SpringBoot项目源码、SSM项目源码 系统展示 【2025最新】基于pythondjangovueMySQL的热…