为什么私有部分被视为接口?

时间:2016-07-26 05:25:50

标签: oop interface

我正在阅读Grady Booch的书面向对象的分析和应用程序设计,第三版。在第94页,Booch说:

  

我们可以将一个类的接口分为四个部分:

     
      
  1. 公开:所有客户都可以访问的声明
  2.   
  3. 受保护:只能由类本身及其子类
  4. 访问的声明   
  5. 私有:只能由类本身访问的声明
  6.   
  7. 包:只能由同一包中的类访问的声明
  8.   

我可以理解为什么保护声明可以被认为是一个接口,因为类的子类也是这个类的客户端。

但我不明白为什么私有声明可以被视为接口。请点缀我。

2 个答案:

答案 0 :(得分:3)

  

但我不明白为什么可以将private声明视为接口。

可以说私有声明构成一个接口,因为它们有自己的客户端,但不像一个类的受保护或公共接口那么多。

这些客户是:

  1. 课程本身。显然,您可以访问您的课程'来自任何类实例的静态或非静态方法的private个成员。
  2. 班级的内部班级。请记住,班级的内部班级可以访问班级的所有成员,包括private个班级。
  3. (在C ++中) 您班上的朋友。 虽然从您问题的引用中我看到您所引用的书是关于Java的,我和#39; lll无论如何都会添加此项,因为您的问题未被标记为java在C ++中有一个friend关键字,它允许一个类的程序员指定某些其他类和/或函数作为此类的朋友。这样的友好"类和函数可以访问该类的所有成员,包括private个成员,因此他们也是该类的客户。私人接口。
  4. 因此,拥有一个定义良好的私有接口可能很有用,因为它使您的类,其朋友和内部类中的方法的实现更简单,更易于管理其他开发人员,他们可能正在为您的类工作

      

    但是,我仍然找到了一个自己的界面"很奇怪。

    与自身的接口可能很重要。这是一个小小的思想实验。

    想象一下,两个开发人员Alice和Bob正在开发同一个类,名为MissileLauncher。鲍勃负责在导弹发射后实施清除发射台的逻辑。 (这是一种私有机制,公共或受保护接口的客户端可能不会请求清除缓冲区 - 它只是此类的实现细节。)

    因此,Bob知道要清除启动板,必须递减missleCounter,将currentMissle设置为null并调用pendingOperations.remove(this.currentOp)。在类的代码中只有一个地方,必须这样做。 Bob 可以将所有这些封装在一个名为clearLaunchingPad()的私有方法中,但他认为逻辑太简单了,所以他没有打扰。

    几个月后,Alice发现还有另一种情况,需要清除发射台。如果Bob想到了一个适合自己的接口,那么Alice就可以简单地写一个this.clearLaunchingPad()的呼叫,并在几秒钟内完成。但是,正如我们所知,鲍勃并没有。现在,爱丽丝必须去问Bob她需要做些什么来清理垫子。但几个月过去了,鲍勃不再记得实施细节了,或者更糟糕的是,他可能从那时起就被解雇了(考虑到他的编码文化,也没有任何意外)。

    所以现在爱丽丝必须深入研究MissileLauncher的代码,并试图弄清楚她需要做什么,希望鲍勃至少有礼貌来评论他的代码。

    这样几秒就会变成几个小时和几个可能的错误(爱丽丝可能忘记在最后打电话给pendingOperations.remove(this.currentOp)),因为鲍勃没有注意这个班级的设计。与自身接口。

答案 1 :(得分:0)

我再次阅读它,这很简单,只是说接口可以是私有的,受保护的,包装和公共接口,之后他告诉你你需要它以及你如何使用它们:)

私有接口的示例:只能在类内部实现的接口!

public class MyClass
{
    private interface IFoo
    {
        int MyProp { get; }
    }

    private class Foo : IFoo
    {
        int _mamboNumber = 5;
        public int MyProp { get { return _mamboNumber; } set { _mamboNumber = value; } }
    }

    private class FooSec : IFoo
    {
        int _mamboNumber = 10;
        public int MyProp { get { return _mamboNumber; } set { _mamboNumber = value; } }
    }

    public static void Main(string[] args)
    {
        IFoo foo = new Foo();
        int fooProp = foo.MyProp; // return 5
        IFoo foo2 = new FooSec();
        int foo2Prop = foo2.MyProp; // return 10
    }
}