我知道我的问题会在发布后立即被提名关闭,但是让我告诉你,我一直在搜索网站上的一个例子,在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:抽象意味着完全隐藏了实现。那么我上面所做的是抽象?
我发布这个问题是出于沮丧,因为我已经向面试官提供了上述解释,他告诉我,这不是正确的意思。
P.S:请按上述示例回答。我不想要实时的例子或假设。
答案 0 :(得分:11)
选择必要的属性并隐藏不需要的详细信息Abstraction
。对于例如考虑人。人有眼睛,eyeColor,skinColor属性。但是,如果他去银行,那么银行会做他的抽象而不考虑这些人的属性,但它会选择姓名,地址,电话号码。这是抽象。你误解了它。
封装只是意味着将对象状态(属性)和行为(方法)绑定在一起。如果你正在创建类,那么你正在进行封装。
来自wiki:在面向对象的编程语言(如C ++,Object Pascal或Java)中,抽象概念本身已成为声明性语句 - 使用关键字virtual(在C ++中)或抽象(在Java中) )。在这样的声明之后,程序员有责任实现一个类来实例化声明的对象。
答案 1 :(得分: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作为父级。
如果您研究Java中File
所代表的内容,我认为您可以更好地了解abstraction
。文件本身是文件和目录路径名的抽象表示。但是,如果您研究源代码,您会发现它包含几个与其设计private
的属性。
封装,因此可以被认为是保护您的属性不受滥用和抽象的影响,因为可以想到您为外部用户提供了多少简化。
答案 2 :(得分:2)
封装:好吧,也许吧。你有一个非常奇怪的实现,调用者不会看到它。
抽象:我们需要知道你究竟想要做什么。当前界面看起来像整数值的getter / setter。这不是很抽象(并且实现不像那样工作,它做了其他事情)。对于抽象,所执行的操作(或所涉及的对象)需要捕获不仅与具体实现脱离的东西,而且还适用于更广泛的事物(不同的,但仍然相似,因为它们可以被制作为属于同一“抽象”)。你的例子可能只是为了小。
要尝试在示例的基础上进行构建,可能您有一段代码按照大小对业务进行分类。将存在“业务”的抽象,其中包括客户数量,员工数量等。使用此抽象的代码对银行,药店和杂货店也同样有效。
答案 3 :(得分:0)
我相信你可能会误解封装和抽象。
根据黑匣子更清楚地解释封装。内部可以在必要时更改,但公共接口保持不变。话虽如此,你的代码是部分封装的,因为你有一个带有公共getter和setter的私有int(以及一个私有的getter,我认为没有任何目的,但这取决于你)。但是,String name
是公开的,没有吸气剂或装置者;看起来你打算将它作为常量,在这种情况下它应该被声明为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;
}
}
答案 4 :(得分:-1)
java中的封装通过对象和方法自动进行。 你不需要照顾它。 但是,如果您愿意,可以使用不同的隐藏方法来增加复杂性。 因此,其他人将无法破译您的代码。 您可以使用递归函数和复杂方法并添加不必要的代码。 强大的封装!!