Java 超类中的私有方法是否可以在子类中重写?

Java 超类中的私有方法是否可以在子类中重写?,java,inheritance,Java,Inheritance,在Java中可以重写私有方法吗? 如果没有,那么下面的代码是如何工作的 class Base{ private void func(){ System.out.println("In Base Class func method !!"); }; } class Derived extends Base{ public void func(){ // Is this a Method Overriding..?

在Java中可以重写私有方法吗? 如果没有,那么下面的代码是如何工作的

class Base{
      private void func(){
            System.out.println("In Base Class func method !!");         
      };
}

class Derived extends Base{
      public void func(){   //  Is this a Method Overriding..????        
            System.out.println("In Derived Class func method"); 
      }      
}

class InheritDemo{
      public static void main(String [] args){                      
            Derived d = new Derived();
            d.func(); 
      }
}

不,不是。您可以标记覆盖以确保如下所示:

@Override
public void func(){
     System.out.println("In Derived Class func method"); 
}

在这种情况下,这将是一个编译器错误。

不,不能重写私有方法,因为子类不继承其父类的私有成员。您已经为子类声明了一个与超类方法无关的新方法。查看它的一种方法是问问自己在派生类中编写
super.func()
是否合法。重写方法不可能被禁止访问它正在重写的方法,但这里的情况正是如此。

您没有被重写。您不能重写私有成员,您仅仅是在派生中定义一个新方法。自其声明为私有以来,派生没有
func()
的知识库实现。在派生中定义
func()
时不会出现编译器错误,但这是因为派生不知道Base具有
func()
的实现。需要明确的是:如果说您正在重写Base的
func()

否的实现,那是不正确的,因为如果您执行类似
Base b=new-Derived()的操作您仍然无法调用b.func()。你所做的被称为“隐藏”。不,你没有覆盖它。您可以通过尝试用
@Override
标记它,或者尝试调用
super.func()进行检查。两者都不起作用;它们抛出编译器错误

此外,请查看以下内容:

class Base { private void func(){ System.out.println("In base func method"); }; public void func2() { System.out.println("func2"); func(); } } class Derived extends Base { public void func(){ // Is this an overriding method? System.out.println("In Derived Class func method"); } } class InheritDemo { public static void main(String [] args) { Derived D = new Derived(); D.func2(); } } 当您将
Base
中的
func()
更改为public时,它将成为一个覆盖,并且输出将更改为:

func2
In Derived Class func method

由于该方法是私有的,其他类看不到它。因此派生类不继承该方法。
因此,这是而不是重写的情况

方法隐藏将在这里发生,而不是重写。就像在静态情况下发生的一样。

实际上,您并没有重写

重写方法的返回类型必须与父类的方法匹配

但是Java5引入了一种新的功能,称为协变返回类型。您可以用相同的签名覆盖一个方法,但返回返回的对象的子类。换句话说,子类中的方法可以返回一个对象,该对象的类型是该方法返回的具有超类中相同签名的类型的子类。
您可以遵循以下思路:

阅读下面代码段中的注释以找到答案

资料来源:

  • 源代码示例(参考)的学分来自《Jeanne Boyarsky》和《Scott Selikoff》“OCA Oracle认证助理Java SE 8程序员学习指南考试1Z0-808书”

     public class Deer {
            public Deer() { System.out.print("Deer"); }
            public Deer(int age) { System.out.print("DeerAge"); }
            private boolean hasHorns() {  return false; }
            public static void main(String[] args) {
                Deer deer = new Reindeer(5);
                System.out.println(","+deer.hasHorns());// false is printed.
            }
        }
        class Reindeer extends Deer {
            public Reindeer(int age) { System.out.print("Reindeer"); }
            private boolean hasHorns() { return true; } // Overriding possible, but is of no use in the below context.
            // Below code is added by me for illustration purpose
            public static void main(String[] args) {
                Deer deer = new Reindeer(5);
                //Below line gives compilation error.
                //System.out.println(","+deer.hasHorns());
            }
        }
    

  • 私有方法永远不会被滥用。它总是隐藏的

    在您的示例中,派生类有一个父类私有方法,并且有自己的函数func。两者都不同,而且功能也没有过度使用。它是一个独立的功能

    如果在调用父类函数的父类中创建新函数,则如果在方法过度清除的情况下使用父类引用,则将调用父类函数

    注意:对象定义其拥有的成员,引用定义其可以访问的成员

    //方法:清除病例

    class Base{
          public void func(){
                System.out.println("Parent class");         
          };                                                                   
          public void func1(){                                                
                func();                                                             
           }                                                                        
     }
    
    class Derived extends Base{
          public void func(){         
                System.out.println("Derived class"); 
          }      
    }
    
    class InheritDemo{
          public static void main(String [] args){                      
                Derived d = new Derived();                               
                d.func1(); // Prints Derived class                                          
    
                Base b = new Derived();                                    
                b.func1();                                                         // Prints Derived class - no matter parent reference is calling,as there as method is overridden - Check func1() is in parent class, but id doesn't call parent class func() as the compiler finds a func() method over ridden in derived class    
    
          }
    }
    
    // Method Hidding case - Private and static methods case  
    
    class Base{
          private void func(){
                System.out.println("Parent class");         
          };                                                                   
          public void func1(){                                                
                func()                                                              
          }     
    }
    
    class Derived extends Base{
          public void func(){   //  Is this a Method Overriding..????        
                System.out.println("Derived class"); 
          }      
    }
    
    class InheritDemo{
          public static void main(String [] args){                      
                Derived d = new Derived(); 
                d.func1(); // Prints Derived class
                Base b = new Derived();
                b.func1(); 
    // Prints Parent class - the reason is we are using the parent class reference, so compiler is looking for func() and it founds that there is one private class method which is available and is not over ridden, so it will call it. Caution - this won't happen if called using derived class reference.
    
                b.func();
    // this prints the Derived class - the compiler is looking func(), as Derived class has only one func() that it is implementing, so it will call that function. 
    
          }
    }
    

    基类的私有成员不能由类之外的任何人访问,也不能被重写。派生类中的函数是一个可以在任何地方访问的独立函数


    代码将在派生类

    中运行函数,除了已经正确的答案外,请考虑如下:

    public class Private {
        static class A {
            public void doStuff() {
                System.out.println(getStuff());
            }
    
            private String getStuff() {
                return "A";
            }
        }
    
        static class B extends A {
            public String getStuff() {
                return "B";
            }
        }
    
        public static void main(String[] args) {
            A a = new A();
            a.doStuff();
            a = new B();
            a.doStuff();
            B b = new B();
            b.doStuff();
        }
    }
    
    这会打印出来

    A

    A

    A


    尽管
    B
    覆盖了
    getStuff()
    A
    doStuff()
    的实现固定为调用
    A#getStuff()
    ,不会触发多态性。

    Good old
    @Override
    ,非常有用!谢谢你的回复。。但是,即使我在超类final中创建了该方法,代码仍然可以正常工作。。。所以我认为,如果我们在子类中使用相同的方法签名,并使用不同的修饰符,那么它只是创建了一个新的子类方法,而不是重写上面的方法。@PicklishDoorknob哦!!没问题……:)是 啊如果它被重写,那么如果我创建了超类的引用并将基类对象分配给它。t也必须工作,但它不是“…因为它在任何其他类中都不可见。”这是完全错误的。你把可见性和继承性搞混了。不管私有方法是否被子类看到,它们都不能被重写,而且在非常特定的场景中,它们可以被子类看到。@Kröw这确实是一个小小的吹毛求疵。它作为子类的成员不可见,但通过该类的实例,它可以作为封闭类的方法可见。答案的其余部分详细解释了可见性和继承之间的密切关系,因此您的观点是无效的。无论如何,为了解决您的投诉,我对措辞做了一些调整。@Polygenme:+1用于演示它不是覆盖的示例,以及
    @override
    测试。+1用于演示动态分派在这种情况下如何工作(或不工作:D)。添加一点说明会更好。感谢您提供此代码片段,这可能会提供一些有限的短期帮助。通过说明为什么这是一个很好的问题解决方案来正确解释它的长期价值,并将使它对未来有其他类似问题的读者更有用。请在您的回答中添加一些解释,包括您所做的假设。
    public class Private {
        static class A {
            public void doStuff() {
                System.out.println(getStuff());
            }
    
            private String getStuff() {
                return "A";
            }
        }
    
        static class B extends A {
            public String getStuff() {
                return "B";
            }
        }
    
        public static void main(String[] args) {
            A a = new A();
            a.doStuff();
            a = new B();
            a.doStuff();
            B b = new B();
            b.doStuff();
        }
    }