代码之家  ›  专栏  ›  技术社区  ›  Max Yearwood

IntelliJ 2018.1.3显示了接口的所有方法,为什么?[已关闭]

  •  2
  • Max Yearwood  · 技术社区  · 6 年前

    假设我们有以下代码:

    public interface Dvd {
       void startDvd();
    }
    

    和另一个界面:

    public interface Tv {
        void startTv();
    }
    

    和一个班级:

    public class Logitech implements Dvd, Tv {
        @Override
        public void startDvd() {
    
        }
    
        @Override
        public void startTv() {
    
        }
    }
    

    然后,在创建实例时:

    public class Demo {
        public static void main(String[] args) {
            Tv tv = new Logitech();
            tv.  //here when we click the . we expect to see only the startTv() 
                 //method, as the type of our reference is Tv
        }
    }
    

    然而,显示的是:

    an image of my intellij code complete

    这不是在否定抽象OOP的概念吗?因为它总是向我展示我的类实现的接口中的所有方法,有时这可能是大量的方法,对我来说不会隐藏任何复杂性?

    为什么我看到这两种方法,而不仅仅是startTv()?

    3 回复  |  直到 6 年前
        1
  •  5
  •   Michael    6 年前

    这仅适用于局部变量,并且仅当IntelliJ能够确保变量的类型始终是某个具体类型时(在本例中 Logitech ).

    如果我们添加另一个实现 Tv

    class Foo implements Tv {
        @Override
        public void startTv() { }
    }
    

    然后有条件地分配给变量:

    class Demo
    {
        private static int bar()
        {
            return 3;
        }
    
        public static void main(Tv args) {
            Tv tv = new Logitech();
    
            if (bar() > 2)
            {
                tv = new Foo();
            }
    
            tv. //only has startTv method
        }
    }
    

    那么IntelliJ就不能再推断类型了,所以它不会提示我们使用 罗技 (或来自 Foo 或者)。

    对于方法参数也是如此-IntelliJ不知道真正的具体类型,因此它不会提供任何其他方法。

        2
  •  4
  •   azro    6 年前

    这是IntelliJ提供的帮助,如果你按 enter 选择后 startDvd() ,它将替换中的代码 ((Logitech) tv).startDvd();

    如果你去掉这个石膏,你会得到经典 cannot resolve method 'startDvd()'

        3
  •  0
  •   Adam Ramos    6 年前

    实际上,tv对象是Logitech类的一个实例。Intellij试图通过让您知道 可以 如果要使用强制转换,请访问startDvd()方法。

    要告诉你你可以把电视放回Logitech还有很长的路要走。

    然而,如果当时所有的节目都需要一个电视对象,那么最好将电视设置为 机具 直接连接电视接口。

    或者,您可能希望匿名实现它:

        Tv tv = new Tv() {
            public void startTv() {
                //code to start the tv
            }
        }