使用继承时如何进行强封装?

时间:2019-04-18 07:00:33

标签: java oop inheritance encapsulation

对此我真的很陌生,如果这太愚蠢了,我感到抱歉。 我很难决定在Java中使用继承时要使用哪种可见性。

就我所读的内容而言,要获得一个强大的封装,通常将属性设置为私有,然后使用公共方法访问它们。

但是当您具有固有能力时,这是不行的吗?当我阅读Oracle文档时,它说只有公共/受保护的成员才能继承到子类。但是,如果这样做,我会破坏封装吗?

与此同时,我在超类上使用私有属性,并使用公共方法访问子类上的这些字段。例如:

abstract public class Person{

  private String name;

  Person(String name){
    this.name = name;
  }

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

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

public class Employee extends Person {

  private int salary;

  Employee(String name, int salary){
    super(name);
    this.salary = salary;
  }

  public void getDescription(){
    return "Name is " + getName() + " and salary is " + this.salary;
  }

}


4 个答案:

答案 0 :(得分:0)

也许可以查看javadoc上的可见性,但是在您所保护的情况下,正确的关键字是您,您也可以只保留可见性,然后将其默认为打包

答案 1 :(得分:0)

  

我打破封装了吗?

您没有破坏任何东西。受保护的成员在世界其他地方仍然不可见(包中的类和子类除外)。

Modifier    Class   Package Subclass    World
private       N        N       N          N
protected     Y        Y       Y          N

如果您需要直接对其进行控制并绕过可能会破坏该访问权限的getter / setter方法,那么保护字段绝对可以。

另一方面,当您不经常使用专用字段时,专用字段是有意义的:private String name;"Name is " + getName()完全正确,因为您不在乎返回的确切内容-代表名称的任何内容都足够。

根据经验,“使用对特定成员有意义的限制性最高的访问级别。除非有充分的理由,否则请使用private。”

答案 2 :(得分:0)

  

就我所读的内容而言,要获得一个强大的封装,通常将属性设置为私有,然后使用公共方法访问它们。

对于强/正确的封装,您可以将属性设置为private。句号您不应通过任何方法访问这些属性,而应提供使用这些方法来实现业务逻辑某些部分的方法。

  

[...]它说只有公共/受保护的成员才能继承到子类[...]

所有内容都将被继承,对子类来说,它只会不可见。因此它将成为对象的一部分,您无法直接访问它。

  

[使用公共/受保护的属性]但是,如果我这样做,是否会破坏封装?

是的。直接或直接(使内部状态变为私有状态之外)或使用“ getter”或类似方法使内部状态可用时,几乎总是破坏封装。

答案 3 :(得分:0)

出于强大的封装原因,这是将属性设置为私有并使用公用方法(如mutator和accessor)访问它们的正确方法。

  

但是当您具有固有能力时,这是不行的吗?

是的,只有公共/受保护成员可以继承到子类,私有类不能传递到子类。

Modifier    Class Package Subclass World
public        Y      Y        Y      Y
protected     Y      Y        Y      N
no modifier   Y      Y        N      N
private       Y      N        N      N
  

我打破封装了吗?

不是。根据定义,封装是一种保护性屏蔽,可防止该屏蔽之外的代码访问数据,并且一个类中的数据对于其他类而言是隐藏的。通过使用受保护的成员进行继承,子类可以访问数据。

但是,封装的概念是对象内部的信息/数据是隐藏的,并且对象的内部属性或方法只能通过对象本身提供的接口来获取。换句话说,对象内部的细节或逻辑是隐藏的,除非允许对象提供的方法/接口,否则其他对象将无法理解和更改对象的内部细节。

直言不讳,我们只需要了解对象的外部,而无需了解内部结构。例如,我们可以通过getDescription()获取Employee信息,但是我们不需要知道如何获取信息。因此,这似乎是封装的一种应用。

public void getDescription(){
    return "Name is " + getName() + " and salary is " + this.salary;
} // void method can not return a value, modified to the following code
public void getDescription(){
    System.out.println( "Name is " + getName() + " and salary is " + this.salary);
}