Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/308.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 重写可见性较低的方法会导致编译错误_Java_Overriding - Fatal编程技术网

Java 重写可见性较低的方法会导致编译错误

Java 重写可见性较低的方法会导致编译错误,java,overriding,Java,Overriding,我有一个类和一个接口: public interface A { public void getNum(); } public class B { public void getNum() { System.out.println("4"); } } public class C extends B implements A { protected void getNum() { System.out.println("3");

我有一个类和一个接口:

public interface A {
    public void getNum();
}

public class B {
    public void getNum() {
        System.out.println("4");
    }
}

public class C extends B implements A {
    protected void getNum() {
        System.out.println("3");
    }
}

现在我的问题是,为什么这段代码会给出编译错误,我们如何避免它。有什么方法可以在C类中重写此方法吗?

修复错误并重试;)


当您实现一个接口时,您需要强制重写它以提供函数的具体实现(除非实现该接口的类是抽象的)。在您的例子中,您正在实现一个接口,该接口使您实现
getNum()
函数,并且由于重写类,您有另一个具有相同签名的函数,这是不允许的。所以你得到了编译错误


可能的解决方案:您可以使用B作为接口。

为了实现这一点,您可以这样做,因为每个文件只能有一个公共类,并且文件名应该与类的名称相同

public class HelloWorld{

     public static void main(String []args){
        C obj=new C();
        obj.getNum();
     }
}
//interface
interface A {
    public void getNum();
}

 class B {
    protected void getNum() {
        System.out.println("4");
    }
}

 class C extends B implements A {
    public void getNum() {
        System.out.println("3");
    }
}
输出:
3来自Java语言规范:

重写或隐藏方法的访问修饰符(§6.6)必须提供至少与重写或隐藏方法相同的访问,如下所示:

  • 如果重写或隐藏的方法是public,那么重写或隐藏的方法必须是public;否则,将发生编译时错误
请注意,您正试图用具有受保护的访问修饰符的新方法覆盖继承自类
B
(以及接口
A
)的
public
方法
getNum()
。这意味着您试图降低此方法的可见性,但根据规范,此方法是不正确的。
要覆盖此方法,您需要在该方法的新版本中使用
public
access修饰符


为什么你不能降低能见度?看看下面的代码,它使用您的类,但放在其他包中,并问自己“这段代码应该如何运行?”


首先,在Java中重写方法时,作用域应该从低到高。子类方法的范围应该高于超类,例如

有效覆盖

class B {
    protected void getNum() {
        System.out.println("4");
    }

 class C extends B  {
    public void getNum() {
        System.out.println("3");
    }
class B {
    public void getNum() {
        System.out.println("4");
    }

class C extends B  {
    protected void getNum() {
        System.out.println("3");
    }
无效覆盖

class B {
    protected void getNum() {
        System.out.println("4");
    }

 class C extends B  {
    public void getNum() {
        System.out.println("3");
    }
class B {
    public void getNum() {
        System.out.println("4");
    }

class C extends B  {
    protected void getNum() {
        System.out.println("3");
    }

第二个问题是您创建了两个无效的公共类。您只能在java文件中创建一个公共类。

一个java类文件只能有一个公共类或接口。 将接口和定义类的可见性更改为默认级别或在单独的文件中声明

只有公共和抽象修饰符可以应用于接口方法。实现接口的类不能更改方法的可见性(我们不能将其从public更改为protected)。

的解释完全正确,即您不能降低被覆盖的
接口
函数的可见性。
让我们来考试一下

 class B 
 {
    protected void getProtected1() 
    {
        System.out.println("4");
    }

    protected void getProtected2() 
    {
        System.out.println("4");
    }

    public void getPublic1() 
    {
        System.out.println("4");
    }

    public void getPublic2() 
    {
        System.out.println("4");
    }

}

class C extends B
{
    @Override
    private void getPublic1() //COMPILATION ERROR : Cannot reduce the visibility of the inherited method from myzeromqApp.B
    {
        System.out.println("3");
    }

    @Override
    protected void getPublic2() //COMPILATION ERROR :Cannot reduce the visibility of the inherited method from myzeromqApp.B
    {
        System.out.println("3");
    }

    @Override
    private void getProtected1() //COMPILATION ERROR : Cannot reduce the visibility of the inherited method from myzeromqApp.B
    {
        System.out.println("3");
    }

    @Override
    public void getProtected2() // NO ERROR IT MEANS YOU ARE ALLOWED TO INCREASE THE VISIBILITY
    {
        System.out.println("3");
    }       
}
从上面的示例可以清楚地看出,在任何情况下都不允许降低函数的可见性。

在您的问题中您正在尝试实现
接口
功能,我们知道Java中的
接口
有如下规则:

  • 方法:只允许
    公开
    摘要
  • 字段:(变量)仅允许
    公共
    静态
    最终

根据经验,您永远不能降低
重写的
或实现的方法或变量的可见性,对于
接口
,它始终是
公共的
(如果涉及可见性),因此在实现的类中,这些类应该始终是
公共的。

如上所述,每个文件只能使用一个公共类。因此,要将它们全部公开,必须创建三个单独的.java文件。我将在下面编写代码,并详细说明如何重写该方法,以便在每种情况下使用正确的版本

可能总是有同名的方法,但为了重写,它们必须有不同的参数列表。这是一个编译器错误,您有三个具有相同参数列表的方法,即none。您可以使用正确的参数列表创建并调用该方法,以获得所需的结果

A.java:

package stackOverflow.tests; // Sample package for visibility

public Interface A {
    public void getNum(int a); // Method takes a single integer argument
}
B.java:

package stackOverflow.tests;

public class B {
    protected void getNum(int a, int b) { // Method takes two integer arguments, differing in the argument list but equal in name
        System.out.println("4");
    }
}
C.java:

package stackOverflow.tests;

import stackOverflow.tests.A; // Importing both classes to use their methods
import stackOverflow.tests.B;

public class C extends B implements A {
    public void getNum(int a, String x) { // Takes an integer and a string argument
            System.out.println("3");    
    }    

    public void getNum(int a) {
        //Do nothing, as in A.java, this code is necessary to be able to override the method.
    }

    public static void main(String[] arguments) { // Sample main method for implementation
        C c = new C(); // Instantiating class C
        int test = 0; // Initializing two integer variables and one String variable
        int test2 = 0;
        String test3 = "";
        c.getNum(test); // takes one integer, using getNum() from A.java
        c.getNum(test, test2); // takes two integers, using getNum() from B.java
        c.getNum(test, test3); // takes an integer and a String, using getNum() from C.java
    }
}
输出:

4
3

如上面代码所示,参数列表定义了使用的方法版本。作为一个小提示,定义
getNum(inta)
getNum(intb)
没有什么不同,因此这将导致它无法编译。

泄露秘密。编译错误是什么?为了更好的世界缩进你的代码。为什么不重命名B.getNum()?在JavaC1.7.0_45上对我来说很好。@200_成功这个问题是。现在编辑完成了,编译错误又回来了。现在C类通过继承有了B类方法。现在我只想实现A类的方法。可能的解决方案是什么。@实际上它可以毫无问题地编译,只要您将所有公共类和接口放在单独的
.java
文件中,因为每个
.java
文件只能有一个公共类,并且该类的名称必须与您在文件中使用的名称相同,如
MyClass.java
可以有
公共类MyClass
@Pshermo,他可以将所有类放在单个文件。@michali true,但在这种情况下,其中只有一个可以是
public
@Pshemo,它可以始终是嵌套类:@michali我怀疑如果是这种情况,OP会提到:)所有的文件都在不同的文件中。