使用getter和setter的优点是什么 - 只能获取和设置 - 而不是简单地使用公共字段来存储这些变量?
如果getter和setter做的不仅仅是简单的get/set,我可以非常快地解决这个问题,但我并不是100%清楚如何:
public String foo;
Run Code Online (Sandbox Code Playgroud)
更糟糕的是:
private String foo;
public void setFoo(String foo) { this.foo = foo; }
public String getFoo() { return foo; }
Run Code Online (Sandbox Code Playgroud)
而前者需要很少的样板代码.
我知道这是一个非常基本的问题,但是一位采访者以非常戏法的方式问我,我很无奈:(
我只知道接口的材料或理论定义,并且在我工作的许多项目中也实现了它.但我真的不明白为什么以及如何有用.
我也不了解界面中的一件事.即,例如,我们使用
conn.Dispose();在最后一块.但我没有看到该类正在实现或继承IDisposableinterface(SqlConnection)类我的意思.我想知道如何调用方法名称.同样,我不了解Dispose方法是如何工作的,因为我们需要使用我们自己的实现为所有接口方法实现函数体.接口如何被接受或命名为合同?到目前为止,这些问题一直在我心中滚动,坦率地说,我从来没有看到任何能以我能理解的方式解释我的问题的好线程.
MSDN像往常一样看起来非常可怕,没有一行是明确的(伙计们,善意的理由是谁进入高级开发,我强烈认为任何代码或文章应该达到任何人看到它的想法,因此像许多人说的那样,MSDN是没用的).
采访者说:
他有5种方法,他很乐意直接在课堂上实现它,但如果你必须选择抽象类或接口,你选择哪一种,为什么?我确实回答了他在各种博客中读到的所有内容,说明抽象类和界面的优缺点,但他不相信,他试图理解"为什么界面"."为什么抽象类"一般,即使我只能实现相同的方法一次而不是改变它.
我看不到网络中的任何地方,我可以得到一篇文章,可以清楚地解释我的接口及其功能.我是众多程序员中的一员,他们仍然不了解接口(我知道我使用的理论和方法)但不满意我清楚地理解它.
通常在Scala文献中,我遇到了"抽象结束"这个短语,但我不明白其意图. 例如,马丁奥德斯基写道
您可以将方法(或"函数")作为参数传递,也可以对它们进行抽象.您可以将类型指定为参数,也可以对它们进行抽象.
另一个例子,在"弃用观察者模式"一文中,
我们的事件流是第一类值的结果是我们可以抽象它们.
我已经读过第一阶泛型"抽象类型",而monads"抽象类型构造函数".我们还在Cake Pattern论文中看到了这样的短语.引用许多这样的例子中的一个:
抽象类型成员提供了抽象的具体类型的组件的灵活方式.
即使相关的堆栈溢出问题也使用此术语. "不能存在抽象的参数化类型..."
所以......"抽象"究竟意味着什么?
"泄漏抽象"一词是什么意思?(请用例子解释.我经常很难完成一个理论.)
memory-leaks abstraction programming-languages functional-programming leaky-abstraction
像这样的问题的答案:List <T>或IList <T>似乎总是同意返回一个接口比返回一个集合的具体实现更好.但我正在努力解决这个问题.实例化接口是不可能的,因此如果您的方法返回一个接口,它实际上仍然返回一个特定的实现.我通过编写两个小方法来尝试一下这个:
public static IList<int> ExposeArrayIList()
{
return new[] { 1, 2, 3 };
}
public static IList<int> ExposeListIList()
{
return new List<int> { 1, 2, 3 };
}
Run Code Online (Sandbox Code Playgroud)
并在我的测试程序中使用它们:
static void Main(string[] args)
{
IList<int> arrayIList = ExposeArrayIList();
IList<int> listIList = ExposeListIList();
//Will give a runtime error
arrayIList.Add(10);
//Runs perfectly
listIList.Add(10);
}
Run Code Online (Sandbox Code Playgroud)
在这两种情况下,当我尝试添加新值时,我的编译器没有给我任何错误,但显然IList<T>当我尝试向其添加内容时,将我的数组公开为暴露的方法会产生运行时错误.因此,那些不知道我的方法中发生了什么,并且必须为其添加值的人,被迫首先将我复制IList到a List以便能够添加值而不会有错误.当然,他们可以做一个类型检查,看看他们是否正在处理a List或者a Array,但是如果他们不这样做,并且他们想要将项目添加到集合中,他们别无选择将其复制IList到a List,即使它已经是一个List.数组永远不会暴露为IList?
我的另一个问题是基于相关问题的接受答案(强调我的):
如果您通过其他人将使用的库公开您的类, …
我正在准备面试,并决定刷新我的OOP概念.有数百篇文章可供使用,但似乎每篇文章都有不同的描述. 有人说
抽象是"识别具有系统变化的共同模式的过程;抽象代表了常见模式,并提供了指定使用哪种变体的方法"(Richard Gabriel).
并通过抽象类实现.
一些其他的说
抽象意味着仅向对象的客户端显示必要的细节
和
假设您的Employee类中有一个方法"CalculateSalary",它将EmployeeId作为参数,并将当前月份的员工薪水作为整数值返回.现在,如果有人想要使用该方法.他不需要关心Employee对象如何计算薪水?他唯一需要关注的是方法的名称,输入参数和结果成员的格式,
我一遍又一遍地搜索,结果似乎没有给我一个正确的答案. 现在,封装在哪里适合所有这些? 我搜索并发现了堆栈溢出问题.即使答案到问题被混淆 在这里,它说
封装是一种用作抽象的一部分的策略.封装是指对象的状态 - 对象封装其状态并将其隐藏在外部; 类的外部用户通过其方法与之交互,但无法直接访问类状态.因此,该类抽象出与其状态相关的实现细节.
而这里的另一个知名的成员说,
它们是不同的概念.
抽象是精炼对象的所有不需要/不重要的属性并且仅保留最适合您的域的特征的过程.
现在我搞砸了整个概念.我知道抽象类,继承,访问说明符和所有.我只是想知道在面试中被问及抽象和/或封装时我该如何回答.
请不要将其标记为重复.我知道有几个类似的问题.但我想避免相互矛盾的解释之间的混淆.任何人都可以提出可靠的链接吗?除非再次造成混淆,否则也欢迎链接到stackoverflow问题.:)
编辑:我需要答案,有点c#导向
在面向对象的程序中:抽象多少太多了?多少钱是对的?
我一直都是一个坚定的人.我理解高级封装和抽象背后的概念,但总觉得增加太多只会混淆程序.
我总是试图拍摄一些没有空类或层的抽象.如果有疑问,我会尝试在现有图层中添加一些新图层,而不是在层次结构中添加新图层.
然而,最近我遇到了更多高度抽象的系统.系统中可能需要在层次结构中稍后表示的所有内容都可以预先获得.这导致了很多空层,起初看起来像是糟糕的设计.然而,第二个想法我已经意识到,留下那些空白的层将为你提供更多的地方,以便将来不需要太多的重构.它使你能够更好地在旧版本之上添加新功能,而无需做太多调整旧版本的工作.
这样做的两个风险似乎是你可以得到你需要错误的图层.在这种情况下,人们最终还是需要进行大量的重构来扩展代码,并且仍然会有大量未使用的层.但是,根据您花费多少时间进行初始抽象,将其搞砸的可能性,以及如果您做得对,可以节省的时间 - 可能仍然值得尝试.
我能想到的另一个风险是过度做的风险,从不需要所有额外的层.但那真的很糟糕吗?额外的类层真的如此昂贵,如果从未使用它们会有很大的损失吗?这里最大的费用和损失将是前面提到的层丢失的时间.但是,当人们可以使用抽象代码而不是更低级别的代码时,大部分时间仍然可以保存.
那么什么时候太多了?空白层和额外的"可能需要"抽象在什么时候变得有点过分?太少了?甜蜜点在哪里?
您在职业生涯中是否有任何可靠的经验法则可以帮助您判断所需的抽象量?
学习OOP概念特别有兴趣深入了解抽象和封装.
已经查看了下面的内容
我发现用一个真实而简单的示例类/代码片段很难理解这些概念.
我的一位同事说抽象只不过是创建抽象类和普通类来保护其成员变量的范围称为封装.
是否有一种简单的方法可以理解并帮助其他人了解它们究竟是什么,而不是重复下面的内容?
抽象和封装是互补的概念:抽象侧重于对象的可观察行为......封装侧重于产生这种行为的实现......封装通常是通过信息隐藏来实现的,这是隐藏所有内容的过程.对象的秘密不会对其基本特征产生影响.