6

我知道我的问题将被提名为在发布后立即关闭,但让我告诉你,我一直在搜索该站点,以在 Java 示例方面寻找明显的区别。请不要急于结束问题。

我写了以下内容:

public class Bank {
public String name="XXX Bank";
private int noOfCust;

public int getNoOfCust() {
 return getNoOfCusts() + 2;
}
public void setNoOfCust(int noOfCust) {
if(noOfCust > 0)
{
this.noOfCust = noOfCust;
}
}

private int getNoOfCusts()
{
noOfCust = 100;
return noOfCust;
}
}

在这里,“noOfCust 是被隐藏的数据”。我不是通过引入私有 getNoOfCusts() 来公开实现部分。所以我相信这是封装,因为我已经将所有细节都捆绑在一个类中,并且也隐藏了数据。

问题1:如果这种强封装?如果没有,我该如何改进它以进行强封装?

问题2:抽象意味着完全隐藏实现。那么我上面所做的是抽象吗?

我出于沮丧而发布了这个问题,因为我已经向面试官解释了上述解释,他告诉我,这不是正确的意思。

PS:请按照上面的例子回答。我不想要实时的例子或假设。

4

5 回答 5

12

选择必要的属性并隐藏不需要的细节是Abstraction. 例如考虑人。人有眼睛、眼睛颜色、皮肤颜色属性。但是如果他去银行,那么银行做他的抽象并且不考虑这些人的属性,而是选择姓名、地址、电话号码。这是抽象。你误会了。

封装只是意味着将对象状态(属性)和行为(方法)绑定在一起。如果你正在创建类,你正在做封装。

来自wiki:在 C++、Object Pascal 或 Java 等面向对象的编程语言中,抽象的概念本身已成为一种声明性声明——使用关键字 virtual(在 C++ 中)或 abstract(在 Java 中)。在这样的声明之后,程序员有责任实现一个类来实例化声明的对象。

于 2012-08-29T06:43:29.523 回答
3
  • 背后的基本思想是在类定义之外encapsulation隐藏视图的内部表示。object这样做通常是为了保护类的内部并提供一种系统的方式来访问它们。

  • 此外,getter/setter组合背后的想法是提供一种访问该类属性的受控方式。因此,对于类的每个private属性,您将拥有public setter()getter()方法。

考虑到这两个,您可以很好地了解为什么您的代码在封装方面存在问题。实现了这个概念的骨架类可能如下:

public class Bank{
    private int noOfCustomers;
    private String name;


    public String getName(){
        return this.name;
    }

    public void setName(String name){
        this.name = name;
    }

    public int getNoOfCustomers(){
        return this.noOfCustomers;
    }

    public void setNoOfCustomers(int noOfCustomers){
        this.noOfCustomers = noOfCustomers;
    }

    /**
    * This method is to illustrate that it is perfectly valid to have
    * multiple types of setter methods
    */
    public void setNoOfCustomers(String noOfCustomers){
        try{
            this.noOfCustomers = Integer.parseInt(noOfCustomers);
        }catch(Exception exe){
            //Handle exceptions
        }
    }
}

关于abstraction:您可以将其视为以简化的方式呈现某些东西的想法,这在使用方面很容易理解或更与情况相关。以您的示例为例,您可以将其Bank视为abstraction既可以代表联邦银行也可以代表州会员银行或任何与此相关的任何事物。您基本上会为这些表示中的每一个派生特定的类,以 Bank 作为父级。

abstraction我认为如果您研究FileJava 中的代表,您可以更好地了解。文件本身是文件和目录路径名的抽象表示。但是,如果您研究源代码,您会发现它包含几个private与其设计相关的属性。

封装,因此可以被认为是您如何保护您的属性免受滥用和抽象,因此可以认为您为外部用户提供了多少简化。

于 2012-08-29T06:47:09.830 回答
2

封装:好吧,也许吧。你有一个非常奇怪的实现,调用者看不到它。

抽象:我们需要知道你实际上想要做什么。当前接口看起来像整数值的 getter/setter。这不是很抽象(并且实现不是那样工作的,它会做其他事情)。对于抽象,执行的操作(或涉及的对象)需要捕获不仅与具体实现分离的东西,而且还适用于更广泛的东西(不同但仍然相似,因为它们可以被制作成属于同一个“抽象”)。你的例子可能只是小到这个。

为了尝试在示例的基础上进行构建,也许您有一段代码可以按企业规模对企业进行分类。将存在具有诸如客户数量、员工数量等属性的“业务”的抽象。使用这种抽象的代码同样适用于银行、药店和杂货店。

于 2012-08-29T06:50:24.193 回答
0

我相信你可能误解了封装和抽象。

用黑匣子更清楚地解释了封装。内部可以随时更改,但公共接口保持不变。话虽如此,您的代码是部分封装的,因为您有一个带有公共 getter 和 setter 的私有 int(以及一个私有 getter,我认为这没有任何意义,但这取决于您)。但是,String name是公共的,没有 getter 或 setter;看来您打算将其设为常量,在这种情况下,应将其声明为 public、static 和 final。

抽象是将一个想法简化为更一般的开销想法的概念。在Java中,一个类可以通过提供一个提供一般思想但缺乏细节的实现来抽象化,并且它不能被实例化。这是通过abstract修饰符实现的,在修改类时,表示抽象类不能被实例化;修改方法(必须在抽象类中)时,修饰符表示必须在任何子类实现中定义抽象方法。

Java 中的抽象示例,其中抽象表明 Baseball 是一个 Ball:

public abstract class Ball {
    // this class cannot be instantiated
    public abstract double getRadius();

    public double getVolume() {
        return (4.0 / 3) * Math.PI * Math.pow(getRadius(), 3);
    }
}

public class Baseball extends Ball {
    // this class can be instantiated
    @Override
    public double getRadius() {
        return 3.0;
    }
}
于 2012-08-29T06:42:06.477 回答
-1

java中的封装是通过对象和方法自动进行的。你不需要照顾它。但是,如果您愿意,您可以使用不同的隐藏方式来增加您的复杂性。因此,其他人将无法破译您的代码。您可能会使用递归函数和复杂的方法并添加不必要的代码。强封装!!

于 2012-08-29T06:43:42.637 回答