当前位置: 首页 > 知识库问答 >
问题:

封装Java

闽经纬
2023-03-14

我实现了一个名为mobile eCall的类。我从这个类中创建了几个对象,并用来自XML的值填充该对象的String变量,该XML具有针对特定人员的多个mobile eCall。我需要对这个人发出的所有呼叫进行分组和计数(例如,国内呼叫:11分钟;国际呼叫:15分钟;数据:20 MB)

因此,我在类中实现了几个公共方法来检查调用的类型,以返回true或false。在主类中,我调用了这些方法来检查它们是否满足标准,我计算了具体的计数器。

有一位专业人士看到了我的代码,说这不是一个好的实践,而OOP旨在消除这种“what at you”方法。还有更好的方法来实现这种行为。我试图通读OOP和封装,但找不到更好的方法。我觉得他说得有道理。

代码示例

public class MobileCall {

    String callType;
    String callDuration;
    String callAmount;
    String callerID;
    String calleID;
    ....
    public boolean isNational(){

        if (callType.compareTo("National")==0)
            return true;
        else
            return false;
    }

    public boolean isInternational(){

        if (callType.compareTo("international")==0)
            return true;
        else
            return false;
    }
    ...
}

In Main Method

int nationalCounter;
int internationalCounter;
MobileCall mobileCall = new MobileCall();

if(mobileCall.isNational())
    nationalCounter = nationalCounter + mobileCall.getCallDuration();
else if (mobileCall.isInternational())
    internationalCounter = internationalCounter + mobileCall.getDuration();
....

共有3个答案

邹山
2023-03-14

嗯,如果你想把本地电话和国际电话分开(或者在更多的国家组中把国际电话分开),它的可扩展性不是很强。从面向对象的角度来看,您可以创建MobileCall的子类型,但这是一种过分的做法(尤其是在没有与不同类型相关联的功能的情况下)。

我会创建一个枚举

public enum CallType { NATIONAL, INTERNATIONAL, DATA, ... } 

并将字符串标识符映射到枚举值(如果选择得当,就不必为此做太多)。创建一个MobileCalltaly类(由地图支持)

mobileCallTally.inc(call.getType(), call.getAmount());

(当然,你可以只使用字符串作为键,完全避免枚举,但由于它是一个类型,我个人喜欢它的类型。)

杨选
2023-03-14

isNational这样的方法可以很好地确定对象的状态,但是如果您使用它们来确定对象的类型,那么使用继承类型可能会更好。

public class NationalMobileCall extends MobileCall 
{
}
轩辕阳焱
2023-03-14
private String callType;

....
public boolean isNational(){

    if (callType.compareTo("National")==0)
        return true;
    else
        return false;
}

public boolean isInternational(){

    if (callType.compareTo("international")==0)
        return true;
    else
        return false;
}

是相关代码。重点是(现在,callType已被强封装)。

三个月后,有人抱怨程序占用了太多内存。你重新审视了你的代码,并决定字符串可能不是确定呼叫国籍的最佳方式,毕竟它要么是国际性的,要么不是,对吗?这意味着你最多需要一位来存储数据。

你来做改变

private boolean nationalCall;

然后改变使用这些数据的方法

public boolean isNational() {
  return nationalCall;
}

public boolean isInternational() {
  return !nationalCall;
}

由于您正确地封装了“国家调用数据”,您可以放心,您不再需要搜索程序的其余部分来确保程序的其他部分能够正常工作。更改的“效果”被“封装”在类“接口”的“边界”处,该接口实际上是由许多“成员方法”实现的。

现在像这样编码

if (mobileCall.isNational()) {
    nationalCounter = nationalCounter + mobileCall.getCallDuration();
} else if (mobileCall.isInternational()) {
    internationalCounter = internationalCounter + mobileCall.getDuration();
}

看起来很可疑。请注意,这段代码似乎非常关注不同类的数据和方法。也许是外部管理班级到了行为位置错位的程度?

如果您将这些方法添加到“Call”类中

public int getNationalMinutes() {
  if (national) {
    return callDuration;
  }
  return 0;
}

public int getInternationalMinutes() {
  if (!national) {
    return callDuration;
  }
  return 0;
}

然后你可以把你的累积代码减少到

while (Call call : client.getAllCalls()) {
  internationalMinutes += call.getInternationalMinutes();
  nationalMinutes += call.getNationalMinutes();
}

请注意,最后一点工作并不是严格意义上的100%封装,因为我们添加了接口项(方法);但是它确实在行为意义上做了一些封装,因为我们不再需要根据一系列查询来确定调用分钟是国际的还是国内的。

对一个类进行一系列检查,以确定如何使用该类的日期,这是“Call”类之外行为的外部迁移。因此,将这种行为移回到类中可能被认为是对类的行为的封装,这与前面的示例不同,后者是对类的数据的严格封装。

很多时候,人们忘记了类封装了数据和行为。感谢您找到一个很好的例子,在这个例子中,封装的两个要点可以在同一个问题中呈现。

 类似资料:
  • 上一小节中,我们已经对类和对象有了一个基本的认识。不止于 Java,在各个面向对象语言的书籍资料中,都会提到面向对象的三大特征:封装、继承、多态。本小节我们就从封装开始,探讨面向对象的特征。本小节我们将学习什么是封装、为什么需要封装,最后也会以一个 NBA 球员类的案例来实现封装。 1. 概念和特点 类的基本作用就是封装代码。封装将类的一些特征和行为隐藏在类内部,不允许类外部直接访问。 封装可以被

  • 6.6. 封装 一个对象的变量或者方法如果对调用方是不可见的话,一般就被定义为“封装”。封装有时候也被叫做信息隐藏,同时也是面向对象编程最关键的一个方面。 Go语言只有一种控制可见性的手段:大写首字母的标识符会从定义它们的包中被导出,小写字母的则不会。这种限制包内成员的方式同样适用于struct或者一个类型的方法。因而如果我们想要封装一个对象,我们必须将其定义为一个struct。 这也就是前面的小

  • prototype对象 构造函数的缺点 prototype属性的作用 原型链 constructor属性 Object.getPrototypeOf方法 Object.create方法 isPrototypeOf方法 prototype对象 构造函数的缺点 JavaScript通过构造函数生成新对象,因此构造函数可以视为对象的模板。实例对象的属性和方法,可以定义在构造函数内部。 function

  • 主要内容:1、public,2、private,3、protected,4、internal,5、protected internalC# 是一门面向对象编程语言,面向对象编程语言有三大特性,分别是封装、 继承和 多态。所谓封装就是将一个或多个项目(函数)集合在一个单元中,这个单元称之为类,我们可以根据需要通过访问权限修饰符来设定类中成员的范围和可见性。C# 中的访问权限修饰符有以下几种: public:公共的,所有对象都可以访问,但是需要引用命名空间; private:私有的,类的内部才可以访

  • 主要内容:Python 类如何进行封装?不光是 Python,大多数面向对象编程语言(诸如 C++、 Java 等)都具备 3 个典型特征,即封装、继承和多态。其中,本节重点讲解 Python 类的封装特性,继承和多态会在后续章节给大家做详细讲解。 简单的理解封装(Encapsulation),即在设计类时,刻意地将一些属性和方法隐藏在类的内部,这样在使用此类时,将无法直接以“类对象.属性名”(或者“类对象.方法名(参数)”)的形式调用

  • Encapsulation被定义为“将一个或多个项目封装在物理或逻辑包中的过程”。 在面向对象的编程方法中,封装阻止了对实现细节的访问。 抽象和封装是面向对象编程中的相关特征。 抽象允许使相关信息可见,封装使程序员能够implement the desired level of abstraction 。 使用access specifiers实现封装。 access specifier定义类成员