在采访中,我被要求解释抽象和封装之间的区别.我的答案一直是这样的
抽象使我们能够以最简单的方式表现复杂的现实世界.它是识别对象应具备的相关品质和行为的过程; 换句话说,表示必要的特征而不表示背景细节.
封装是将对象的所有内部细节隐藏在外部现实世界中的过程."封装"一词,就像"封闭"成"胶囊".它限制客户端看到其实现抽象行为的内部视图.
我认为通过上面的回答,面试官确信,但后来我被问到,如果两者的目的都隐藏了,那么为什么需要使用封装.那时候我没有一个好的答案.
我应该添加什么来使我的答案更完整?
在Python中,我有以下示例类:
class Foo:
    self._attr = 0
    @property
    def attr(self):
        return self._attr
    @attr.setter
    def attr(self, value):
        self._attr = value
    @attr.deleter
    def attr(self):
        del self._attr
如您所见,我有一个简单的"私有"属性"_attr"和一个访问它的属性.有很多代码来声明一个简单的私有属性,我认为它不尊重"KISS"哲学来声明所有属性.
那么,如果我不需要特定的getter/setter/deleter,为什么不将所有属性声明为公共属性?
我的答案是:因为封装原则(OOP)说不然!
什么是最好的方法 ?
我想隐藏intellisense成员列表中的公共方法.我创建了一个属性,当应用于方法时,将导致在构造对象时调用该方法.我这样做是为了更好地支持部分课程.问题是在某些环境(例如Silverlight)中,反射无法访问私有成员,甚至是子类的私有成员.这是一个问题,因为所有工作都是在基类中完成的.我必须将这些方法设为公开,但我希望它们不受intellisense的影响,类似于Obsolete属性的工作原理.坦率地说,因为我是关于对象封装的肛门.我尝试了不同的东西,但实际上没有任何效果.该方法仍显示在成员下拉列表中.
当我不希望客户端调用公共方法时,如何防止公共方法出现在intellisense中?对于一个真正的问题,非利士人怎么样!这也适用于必须公开的MEF属性,但有时您希望将它们从客户端隐藏.
更新: 自从发布此问题以来,我已成熟为开发人员.为什么我如此关心隐藏界面是在我之外.
采访者:什么是封装,你如何用Java实现它?
我: 封装是一种隐藏客户端信息的机制.该信息可以是数据或实现或算法.我们使用访问修饰符来实现这一点.
采访者:这是数据隐藏.我们如何在Java中实现封装?
我:uummmm
具体问题:除了'Access Modifiers'之外,在Java中实现Encapsulation的方法是什么?
我如何使用set和get方法,为什么要使用它们?他们真的很有帮助吗?你也可以给我一些set和get方法的例子吗?
在 TypeScript 3.8+ 中,使用private关键字将成员标记为私有有什么区别:
class PrivateKeywordClass {
    private value = 1;
}
并使用为 JavaScript 提议的#私有字段:
class PrivateFieldClass {
    #value = 1;
}
我应该更喜欢一个吗?
我知道这是oops中一个非常基本的概念.但我仍然无法理解.我理解为什么成员变量是私有的,因此类用户不能通过设置无效值来滥用它.
但这怎么能适用于这些方法呢?
假设我需要一个简单的私有帮助器方法,并且直观地在代码中它作为扩展方法是有意义的.有没有办法将该帮助程序封装到实际需要使用它的唯一类中?
例如,我试试这个:
class Program
{
    static void Main(string[] args)
    {
        var value = 0;
        value = value.GetNext(); // Compiler error
    }
    static int GetNext(this int i)
    {
        return i + 1;
    }
}
编译器不"看到" GetNext()扩展方法.错误是:
必须在非泛型静态类中定义扩展方法
很公平,所以我将它包装在自己的类中,但仍然封装在它所属的对象中:
class Program
{
    static void Main(string[] args)
    {
        var value = 0;
        value = value.GetNext(); // Compiler error
    }
    static class Extensions
    {
        static int GetNext(this int i)
        {
            return i + 1;
        }
    }
}
仍然没有骰子.现在错误说明:
必须在顶级静态类中定义扩展方法; 扩展是一个嵌套类.
这个要求有令人信服的理由吗?在某些情况下,辅助方法确实应该是私有封装的,并且如果辅助方法是扩展方法,则存在代码更清晰且更易读/可支持的情况.对于这两者相交的情况,既可以满足,也可以选择其中一种?
为什么不能让所有方法和属性从任何地方(即public)可以访问?
如果我将属性声明为?你能举一个我可以遇到的问题的例子public吗?
我最近讨论了依赖性倒置原则,控制反转和依赖注入.关于这个主题,我们一直在争论这些原则是否违反了OOP的一个支柱,即封装.
我对这些事情的理解是:
辩论与以下声明达成了共识:
IoC不是OOP,因为它打破了封装
就个人而言,我认为所有OOP开发人员应该虔诚地遵守依赖倒置原则和控制反转模式 - 我遵循以下引用:
如果有(可能)不止一种方法给猫皮肤,那么就不要 表现得像只有一只猫.
例1:
class Program {
    void Main() {
        SkinCatWithKnife skinner = new SkinCatWithKnife ();
        skinner.SkinTheCat();
    }
}
在这里,我们看到封装的一个例子.程序员只需要打电话Main(),猫就会被剥皮,但是如果他想给猫咪涂上一层锋利的牙齿呢?
例2:
class Program {
    // Encapsulation
    ICatSkinner skinner;
    public Program(ICatSkinner skinner) {
        // Inversion of control
        this.skinner = skinner;
    }
    void Main() {
        this.skinner.SkinTheCat();
    }
}
... new Program(new SkinCatWithTeeth());
    // Dependency Injection
在这里,我们观察依赖性反转原理和控制反转,因为提供了abstract( …
oop encapsulation design-patterns inversion-of-control solid-principles
encapsulation ×10
oop ×6
c# ×2
java ×2
.net ×1
abstraction ×1
class ×1
class-fields ×1
data-hiding ×1
getter ×1
intellisense ×1
methods ×1
php ×1
private ×1
properties ×1
python ×1
reflection ×1
setter ×1
typescript ×1
visibility ×1