可以在子类中重写超类中的私有方法吗?

时间:2012-08-15 20:06:51

标签: 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..????        
            System.out.println("In Derived Class func method"); 
      }      
}

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

12 个答案:

答案 0 :(得分:46)

不,你没有压倒它。您可以尝试使用@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(); 
      }
}

它将打印:

func2
In base func method

当您将func()中的Base更改为公开时​​,然后它将成为覆盖,输出将更改为:

func2
In Derived Class func method

答案 1 :(得分:20)

不,私有方法无法被覆盖,因为它在任何其他类中都不可见。您已为子类声明了一个与超类方法无关的新方法。查看它的一种方法是问自己在Derived类中编写super.func()是否合法。没有办法禁止重写方法访问它覆盖的方法,但这恰恰就是这种情况。

答案 2 :(得分:3)

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

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

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

答案 3 :(得分:3)

你没有压倒一切。您不能覆盖私有成员,您只是在Derived中定义一个新方法。 Derived没有知道Base的func()实现,因为它被声明为私有。在Derived中定义func()时,您不会收到编译器错误,但这是因为Derived不知道Base具有func()的实现。需要明确的是:说你要覆盖Base的func()实现是错误的。

答案 4 :(得分:2)

除了已经正确的答案外,请考虑以下事项:

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的{​​{1}}实现固定为调用doStuff(),不会触发多态。

答案 5 :(得分:1)

不,因为如果您执行Base b = new Derived();之类的操作,您仍然无法调用b.func()。你正在做的事情被称为“隐藏”。

答案 6 :(得分:1)

永远不能过度使用私有方法。它总是隐藏的。

在您的示例中 - 派生类有一个父类私有方法,并且有自己的函数 func 。两者都不同, func 不会被覆盖。它是一个独立的独立功能。

如果在父类中调用父类函数创建新函数,则将调用父 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. 

      }
}

答案 7 :(得分:0)

由于该方法是私有的,因此其他类不可见。因此派生类不会继承此方法。 所以这是覆盖

的情况

答案 8 :(得分:0)

隐藏方法将在此处发生,而不是覆盖。就像静止的情况一样。

答案 9 :(得分:0)

实际上,你并没有超越。在Java5之前

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

但Java 5引入了一个名为协变返回类型的新工具。您可以使用相同的签名覆盖方法,但返回返回的对象的子类。换句话说,子类中的方法可以返回一个对象,该对象的类型是由超类中具有相同签名的方法返回的类型的子类。   你可以关注这个主题:Can overridden methods differ in return type?

答案 10 :(得分:0)

基类的私有成员无法被类外的任何人访问,也无法被覆盖。 derive类中的函数是一个独立的函数,可以在任何地方访问。

代码将在派生类

中运行该函数

答案 11 :(得分:-1)

阅读以下代码段中的评论以找到答案。

来源:

  1. Definition reference:

  2. 来自本书的源代码示例(参考)的学分 - " OCA Oracle认证助理Java SE 8程序员学习指南考试1Z0-808书"来自' Jeanne Boyarsky'和Scott Selikoff'。

     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());
            }
        }