【问题标题】:Java overriding method ErrorJava覆盖方法错误
【发布时间】:2015-08-21 04:58:47
【问题描述】:

基本上,我创建了一个 Person 类和一个构造函数,用于设置 Person 的名称、姓氏、年龄。该类的所有属性都设置为应有的私有属性。我已经为所有属性制作了 setter 和 getter。在主要方法上,出于实践原因,我尝试覆盖其中一个二传手。它确实绘制了一个错误,说 Person.name 不可见,这意味着它无法访问私有,为什么会发生这种情况,我的意思是如果没有覆盖它可以访问的方法。但如果我将它设置为保护模式,我会工作。 代码如下:

class Person {
    private int age;
    private String name;
    private String last_name;
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getLast_name() {
        return last_name;
    }
    public void setLast_name(String last_name) {
        this.last_name = last_name;
    }
    public Person(int age, String name, String last_name) {
        this.age = age;
        this.name = name;
        this.last_name = last_name;

    }
}


public class main {

    public static void main(String[] args)  {
        // TODO Auto-generated method stub
        Person per = new Person(15,"bb","Sb") {
            public void setName(String name) {
                this.name = "aaaa";
            }
        };
        per.setName("asdfaf");
        System.out.println(per.getName());
    }
}

【问题讨论】:

  • 因为它破坏了封装!
  • 你在哪里覆盖一个方法?我在您发布的代码中的任何地方都没有看到这种情况。
  • public void setName(String name) { this.name = "aaaa"; }
  • 嘿,Tim 方法已被实例化覆盖,
  • Ankur,在 c++ 中是可能的,这怎么会破坏封装?

标签: java


【解决方案1】:

private 成员只能在声明它的类中访问。 您创建了 Person 的匿名子类,并尝试从子类访问超类的 private 成员。这是绝对不允许的。

当类的开发人员希望允许对该类的某些成员访问其子类时,他们将访问级别设置为protected

【讨论】:

  • 谢谢您,先生,我没有意识到我正在创建另一个类。 ,现在一切都说得通了。谢谢!但是它是如何继承私有属性的呢?
  • @jojo 具体来说,这称为匿名子类
  • 所以它继承了私有但不允许访问,这有多奇怪?因为看看构造函数实际上改变了名字,当我做一个吸气剂时它确实返回了名字
  • @jojo 您仍然可以通过公共 getter 和 setter 方法访问和更改 name 成员,因此您确实可以访问。您只是无法直接访问私有成员。
  • 所以它不像一个子类。 ,它是一种特殊的类?
【解决方案2】:

您已经创建了一个名为 Person 的类,并且在以下几行中您尝试创建一个 anonymous subclass

Person per = new Person(15,"bb","Sb") {
            public void setName(String name) {
                this.name = "aaaa";
            }
        };

doc中所述:

子类不继承其父类的私有成员

这里你的匿名子类试图直接访问私有字段name,错误也是如此。您可以使用公开的 getter/setter。你也可以在 SO 上查看这个相关的question

【讨论】:

  • Akhil,如果构造函数本身访问私有属性,你怎么能说它不继承。然后当我对来自子类的新对象做一个吸气剂时,它会得到它吗?
  • @jojo 构造函数访问私有成员,因为它被允许这样做,如公共 setter 方法
【解决方案3】:

您无法从班级外部访问private 字段,即使您正在覆盖它。您基本上是在main() 中定义Person 的新子类,不允许访问private 字段Person.name。但是,它可以访问protected 字段。

【讨论】:

    【解决方案4】:

    覆盖背后的基本思想是重新定义现有功能并为其赋予新定义。如果您引用documentation,私有成员变量只能在它自己的类中访问。这就是为什么它在您的 anonymous 子类实现中不可用的原因。

    注意:通常我们不会覆盖 setter 方法,因为它们不是功能。

    【讨论】:

    • Naman,但我确实可以访问,因为我可以这样做,per.getName(),即使它是一个子类,它也会获得在构造函数上设置的名称
    • 请参考访问修饰符的documentation。其中明确提到公共成员(getName())可以被世界访问,而私有成员(this.name)只能被它自己的类方法和构造函数访问。
    • Naman,我明白了,当我调用超级构造函数时,我将继承父类访问的私有属性,因为它将这些属性赋予新对象。 nvm 我这里明白了原理。
    • 参考 java 中的Inheritance。并首先弄清楚超类与子类的关系,然后尝试理解匿名子类。
    • 只是为了澄清,如果通过继承,你的意思是在子类中使用它,那么你就被误解了。它只会留在超类中,并且可以通过子类中的构造函数、getter 和 setter 访问。
    【解决方案5】:

    这称为封装。您不能从其他类访问私有变量。你可以找到更多描述here

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-01-30
      • 2014-09-28
      相关资源
      最近更新 更多