corejava11(4.10 类设计提示)

本文给出Java类设计的提示,包括保持数据私有、初始化数据、避免用过多基本类型、合理设置访问器和赋值器、拆分责任过多的类、使名称反映职责、选择不可变类等,还指出Java要真正面向对象还需支持继承和多态性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

4.10 类设计提示

在本章结束时,我们不想太过繁琐乏味,我们希望给出一些提示,使您的课程在优雅的OOP圈子中更容易被接受。

  1. 始终将数据保持private。
    这是最重要的;做任何其他事情都违反了封装。您可能偶尔需要编写一个访问或修改方法,但最好还是保留实例字段的私有性。苦涩的经验表明,数据表示可能会改变,但这种数据的使用方式改变的频率要少得多。当数据保持私有时,其表示形式的更改不会影响类的用户,并且更容易检测到错误。

  2. 总是初始化数据。
    Java不会为您初始化局部变量,但它会初始化对象的实例字段。不要依赖默认值,而是通过提供默认值或在所有构造函数中设置默认值来显式初始化所有变量。

  3. 不要在一个类中使用太多的基本类型。

    其思想是用其他类替换基本类型的多个相关用途。这使你的类更容易理解和改变。例如,替换Customer类中的以下实例字段:

    private String street;
    private String city;
    private String state;
    private int zip;
    

    一个叫做Address的新类。这样,您就可以轻松地处理地址的更改,例如需要处理国际地址。

  4. 并非所有字段都需要单独的字段访问器和赋值器。
    您可能需要获取并设置员工的工资。一旦构建了对象,您当然不需要更改招聘日期。而且,通常情况下,对象具有您不希望他人获取或设置的实例字段,例如Address类中的状态缩写数组。

  5. 把责任太多的类分开。
    当然,这个暗示是模糊的:“太多”显然是在旁观者的眼中。但是,如果有一种明显的方法可以将一个复杂的类分成两个概念上更简单的类,那么就抓住这个机会。(另一方面,不要过火;十个类,每个类只有一个方法,通常都是过火的。)
    下面是一个坏设计的例子:

    public class CardDeck // bad design
    {
        private int[] value;
        private int[] suit;
        public CardDeck() { . . . }
        public void shuffle() { . . . }
        public int getTopValue() { . . . }
        public int getTopSuit() { . . . }
        public void draw() { . . . }
    }
    

    这个类实际上实现了两个独立的概念:一组卡片及其shuffle和draw方法,以及一张卡片及其检查其值和大小的方法。引入表示单个卡的Card类是有意义的。现在您有两个类,每个类都有自己的职责:

    public class CardDeck
    {
        private Card[] cards;
        public CardDeck() { . . . }
        public void shuffle() { . . . }
        public Card getTop() { . . . }
        public void draw() { . . . }
    }
    public class Card
    {
        private int value;
        private int suit;
        public Card(int aValue, int aSuit) { . . . }
        public int getValue() { . . . }
        public int getSuit() { . . . }
    }
    
  6. 使类和方法的名称反映它们的职责。
    正如变量应该有反映它们所代表内容的有意义的名称一样,类也应该有意义的名称。(标准库当然包含一些可疑的示例,例如描述时间的Date类。)
    一个好的惯例是类名应该是一个名词(Order),或一个以形容词(RushOrder)或动名词(一个“-ing”字开头的名词,如BillingAddress)。至于方法,遵循存取器方法以小写get(getSalary)开头的标准约定,而mutator方法使用小写set(setSalary)。

  7. 选择不可变类。
    LocalDate类和java.time包中的其他类是不可变的,任何方法都不能修改对象的状态。plusDays等方法不是改变对象,而是返回具有修改状态的新对象。
    变异的问题是,当多个线程试图同时更新一个对象时,它可能同时发生。结果是不可预测的。当类是不可变的时,在多个线程之间共享它们的对象是安全的。
    因此,最好尽可能使类不可变。对于表示值的类(如字符串或时间点),这尤其容易。计算可以简单地生成新值,而不是更新现有值。
    当然,并非所有类都应该是不可变的。如果raiseSalary方法在员工获得加薪时返回一个新的Employee对象,这会很奇怪。

在本章中,我们介绍了使Java成为“基于对象的”语言的对象和类的基础。为了真正面向对象,编程语言还必须支持继承和多态性。对这些特性的Java支持是下一章的主题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值