在没有编译错误的情况下更改对方法的访问

Posted

技术标签:

【中文标题】在没有编译错误的情况下更改对方法的访问【英文标题】:Changing access to methods without a compilation error 【发布时间】:2014-05-25 19:43:38 【问题描述】:

有人可以演示一个简单程序的示例,其中在工作程序中将一种方法的访问权限从私有更改为公共不会导致编译错误,而只会导致程序行为不同?

另外,何时添加新的私有方法会导致编译错误或导致程序行为不同?

【问题讨论】:

你自己没有尝试这个,因为?? 闻起来像作业,你能展示一下你到目前为止的尝试吗? 请注意,当在一篇文章中提出两个问题时,即使它们是相关的,也会令人沮丧。 致所有“你尝试过什么”的人(@WhoAmI 等)——公平地说,这是一个棘手的问题。您要么“得到它”并产生答案,要么在页面上茫然地开始困惑。您希望看到什么样的在制品? @Duncan - 如果问题有 - “我试过这个。但它不起作用/它起作用但我不知道为什么”,那么我不会发表评论: ) 【参考方案1】:

这与继承有关。子类可以拥有与父类中的私有方法具有相同签名的方法,但不能覆盖它。

public class Scratchpad 
    public static void main(String[] args) 
        new Sub().doSomething();
    


class Super 
    public void doSomething() 
        System.out.println(computeOutput());
    

    private String computeOutput() 
        return "Foo";
    


class Sub extends Super 
    public String computeOutput() 
        return "Bar";
    

如果你按原样运行,你会得到Foo。如果您将Super#computeOutput() 更改为public,您将得到Bar。那是因为Sub#computeOutput() 现在会覆盖Super#computeOutput()

【讨论】:

+1 很好的例子。应该鼓励人们使用@Override。 ;)【参考方案2】:

另外何时添加新的私有方法会导致编译错误或导致程序行为不同?

借用马克的代码,如果你给Sub添加私有方法,下面的代码将无法编译,因为doSomething()的可见性已经降低了。

class Super 
  public void doSomething() 
    System.out.println("Foo");
  


class Sub extends Super       
  private void doSomething() 
    System.out.println("Harr!");
  


另外,何时添加新的私有方法会导致编译错误或导致程序行为不同

如果添加的私有方法比前一个更具体,您可以调整程序行为。下面的示例打印“bar”,除非您添加(取消注释)另一个打印“foo”的方法。

public class Test 

  public static void main(String[] args) throws Exception 
    String foo = "hello";
    methodOne(foo);
  

  // private static void methodOne(String args) 
  // System.out.println("foo");
  // 

  private static void methodOne(Object arg) 
    System.out.println("bar");
  

【讨论】:

第二种情况的好例子。值得注意的是,这也可以用来回答第一个问题。如果methodOne(Object)public 并且某些代码正在调用它,那么如果您将methodOne(String) 公开,则该代码将调用更具体的方法而不会出现编译器错误(但是需要重新编译)。

以上是关于在没有编译错误的情况下更改对方法的访问的主要内容,如果未能解决你的问题,请参考以下文章

如何在不编译更改的文件的情况下运行`iex -S mix`?

AWS Amplify 在没有错误日志的情况下无法构建和编译

在没有泛型类约束的情况下,将泛型类型与其默认值进行比较,会产生编译时错误

如何在不反编译的情况下更改已编译的 .class 文件?

如何在不关闭预编译头文件的情况下修复 C1010 错误?

是否可以先编译最近更改的文件?