简体   繁体   English

Java - 隐藏覆盖和修改器最终

[英]Java - Hiding Overriding and the modifier final

I couldn't find a question like mine, so I hope it's not a duplicate one. 我找不到像我这样的问题,所以我希望这不是一个重复的问题。

Again it's about overriding and hiding. 再次,这是关于覆盖和隐藏。 I think - but I might be wrong - I understood both. 我想 - 但我可能错了 - 我理解两者。

The following code behaves as expected, both methods have been hidden. 以下代码按预期运行,两种方法都已隐藏。 method1 because it is a private method and private methods can't be overridden only hidden, method2 because it's static and static methods can't be overridden, they can only be hidden. method1因为它是一个私有方法并且私有方法不能只被隐藏,所以方法2因为它的静态和静态方法不能被覆盖,它们只能被隐藏。

public class Child extends Parent { 
    public void method1(){System.out.println("child");}     
    public static void method2(){ System.out.println("static child");}  
}

class Parent{
    private void method1(){ System.out.println("parent");}      
    public static void method2(){ System.out.println("static parent");}

    public static void main(String[] args){
            Parent p = new Child();
            p.method1(); //prints out "parent"
            p.method2(); //prints out "static parent"
    }
}

If I read the specs it says: 如果我读了规格,它说:

http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.3.3 http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.3.3

A method can be declared final to prevent subclasses from overriding or hiding it. 可以将方法声明为final以防止子类覆盖或隐藏它。

If I change method1 in the Parent class to "final" 如果我将Parent类中的method1更改为“final”

private final void method1(){ System.out.println("parent");}

Everything works fine. 一切正常。 edit start: I expected an compiler error saying that final methods can't be hidden, but that didn't happen. 编辑开始:我期望编译器错误说最终方法无法隐藏,但是没有发生。 :edit end :编辑结束

Question no 1: does that mean only static methods can be hidden? 问题1:这是否意味着只能隐藏静态方法? In the book I'm reading (OCA study guide, Jeanne Boyarsky and Scott Selikoff page 252) they clearly say that a private method was hidden. 在我正在阅读的书中(OCA学习指南,Jeanne Boyarsky和Scott Selikoff,第252页),他们清楚地说隐藏了一种私人方法。

Then I changed method2 in the Parent class to 然后我将Parent类中的method2更改为

public final static void method2(){ System.out.println("static parent");}

Now the compiler does complain, the error says "Child cannot override method2()" which is pretty confusing because I thought I tried to hide a method. 现在编译器确实抱怨,错误说“Child不能覆盖method2()”,这非常令人困惑,因为我以为我试图隐藏一个方法。

Question no 2: Shouldn't it be "Child cannot hide method2()"? 问题2:不应该是“孩子不能隐藏方法2()”?

edit start: I am well aware that no overriding happens here, but as the mentioned specs point out: the modifier final prevents methods to be overridden or hidden, that's why I put it in the title. 编辑开始:我很清楚这里没有重写,但正如上面提到的规范所指出的那样:修饰符final会阻止方法被覆盖或隐藏,这就是我把它放在标题中的原因。 :edit end :编辑结束

Question 1 问题1

Question no 1: does that mean only static methods can be hidden? 问题1:这是否意味着只能隐藏静态方法?

Parent.method1() was not visible in nor inherited by Child simply by virtue of being private . Parent.method1()仅仅因为private而在Child不可见或继承。 So Child.method1() didn't override or hide Parent.method1() , it merely created a new method in Child that had the same name, parameters and return type. 所以Child.method1()没有覆盖或隐藏Parent.method1() ,它只是在Child中创建了一个具有相同名称,参数和返回类型的新方法。

See http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.8.3 : 请参阅http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.8.3

Note that a private method cannot be hidden or overridden in the technical sense of those terms. 请注意,在这些术语的技术意义上,不能隐藏或覆盖私有方法。 This means that a subclass can declare a method with the same signature as a private method in one of its superclasses, and there is no requirement that the return type or throws clause of such a method bear any relationship to those of the private method in the superclass. 这意味着子类可以在其一个超类中声明一个与私有方法具有相同签名的方法,并且不要求这种方法的返回类型或throws子句与该方法中的私有方法具有任何关系。超类。

Question 2 问题2

Question no 2: Shouldn't it be "Child cannot hide method2()"? 问题2:不应该是“孩子不能隐藏方法2()”?

Yes, you are correct. 是的,你是对的。 It should be "hide". 它应该是“隐藏”。 Per the JLS ( http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.8.2 ), 根据JLS( http://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.4.8.2 ),

If a class C declares or inherits a static method m, then m is said to hide any method m', where the signature of m is a subsignature (§8.4.2) of the signature of m', in the superclasses and superinterfaces of C that would otherwise be accessible to code in C. 如果类C声明或继承静态方法m,则m被称为隐藏任何方法m',其中m的签名是m'的签名的子签名(第8.4.2节),在超类和超接口中。否则C中的代码可以访问的C.

"Hiding" is what static methods do to static methods. “隐藏”是static方法对static方法的作用。 "Overriding" is what instance methods do to instance methods. “重写”是实例方法对实例方法的作用。 The two can't be mixed: a static method can't override or hide an instance method, and an instance method can't override or hide a static method. 两者不能混合: static方法不能覆盖或隐藏实例方法,并且实例方法不能覆盖或隐藏static方法。

BTW, my Eclipse compiler gives a similar error message: "Cannot override the final method from Parent" 顺便说一句,我的Eclipse编译器给出了类似的错误消息:“无法覆盖Parent的最终方法”

Well, I'm quite new to java, but I'll try to answer. 好吧,我对java很新,但我会尽力回答。

The difference resides in the fact that you're using different access level modifiers: you're using private on method1() of Parent class and public on method1() on Child class. 所不同的在于这样一个事实,你正在使用不同的访问级别修饰符:您正在使用私有method1()在父类和公共的method1()的儿童类。 In fact, you're not hiding the method as it is not the same method. 实际上,您并没有隐藏该方法,因为它不是同一种方法。 The private modifier specifies that the member can only be accessed in its own class, therefore, you're using a new method when you declare method1() on Child class. private修饰符指定只能在其自己的类中访问该成员,因此,当您在Child类上声明method1()时,您将使用新方法。 Even though, child inherits all methods from Parent (as it extends it), private methods are not inherited. 即使子进程从Parent继承了所有方法(因为它扩展了它),私有方法也不会被继承。 In the case of method2() , as it is declared public , it is inherited by Child class and can be hidden. method2()的情况下,当它被声明为public ,它由Child类继承并且可以被隐藏。

More about it (Taken from oracle tutorials ): 更多关于它(取自oracle教程 ):

Private Members in a Superclass 超级私人会员

A subclass does not inherit the private members of its parent class. 子类不继承其父类的私有成员。 However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass. 但是,如果超类具有访问其私有字段的公共或受保护方法,则子类也可以使用这些方法。

A nested class has access to all the private members of its enclosing class—both fields and methods. 嵌套类可以访问其封闭类的所有私有成员 - 包括字段和方法。 Therefore, a public or protected nested class inherited by a subclass has indirect access to all of the private members of the superclass. 因此,子类继承的公共或受保护嵌套类可以间接访问超类的所有私有成员。

EDITED: Question 2: 编辑:问题2:

You hide a static method, not a final one. 您隐藏静态方法,而不是最终方法。 Only static ones can be hidden as in here: 只有静态的可以隐藏在这里:

class SuperClass {
    static void display() {
        System.out.println("Super");
    }
}

class SubClass extends SuperClass {
    static void display() {
        System.out.println("Sub");
    }
}

public class Test {
    public static void main(String[] args) {
        // Prints "Super" in console
        SuperClass sup = new SubClass();
        sup.display();

        // Prints "Sub" in console
        SubClass sub = new SubClass();
        sub.display();
    }
}

You use the final keyword in a method declaration to indicate that the method cannot be overridden by subclasses. 您在方法声明中使用final关键字来指示子类不能覆盖该方法。 So, if you change it, you are overriding it and, therefore, compiler says: 所以,如果你改变它,你就会覆盖它,因此,编译器说:

overridden method is static,final (notice the final ). overridden method is static,final (注意final )。

Compiler complains about it because you're not longer hiding it. 编译器抱怨它,因为你不再隐藏它。 As you declared it final , you're overriding it. 当你宣布它是final ,你就会覆盖它。 It will give you the same error, if you do not use the static modifier on the Child class as you'll be trying to override what it is no longer static . 如果你不在Child类上使用static修饰符,它将给你相同的错误,因为你将试图覆盖它不再是static Hiding is only used when the static method hides another static method. 隐藏仅在静态方法隐藏另一个静态方法时使用。 If you try: 如果你试试:

  1. nonstatic method "hides" static one: that is override. 非静态方法“隐藏”静态方法:即覆盖。
  2. final method "hides" static one: that is override. final方法“隐藏”静态方法:即覆盖。

In those cases, you're not trying to hide anymore (because hiding is use only on static) but you're trying to override. 在这些情况下,你不再试图隐藏(因为隐藏仅用于静态),但你试图覆盖。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM