【问题标题】:Have I done this correctly? (Interface and Class code to compile successfully)我做对了吗? (接口和类代码编译成功)
【发布时间】:2021-07-15 14:31:19
【问题描述】:

给定:考虑以下接口和类:C 类的代码必须满足哪些条件才能成功编译?

    public interface I {
    public void m1();
    public void m2();
    }


    public class C implements I {
      // code for class C
    }

这是我的(以前的)答案:

    public interface I {
    public void m1();

    default public void m2 {
        System.out.println("default m2");
      }
    }

    public class C implements I {
       public void m1()
      }
    C c = new C();          
    c.m2();

有什么办法可以改善吗?我是否对原始代码更改了太多?这是我的作业,但我需要反馈。我是接口新手。任何帮助表示赞赏!

编辑:我试过这样做

    interface I {
    public void m1();
    public void m2();
}

public class C implements I {
    public static void main(String[] args){
        public void m1() {
            System.out.println("To be honest..");
        }
        public void m2() {
            System.out.println("It's a vague question to begin with.");
    }
}

class Main {
    public static void main(String[] args) {
    C why = new C();  
    why.m1();
    why.m2();
    }
}

输出:

错误:表达式的非法开头 public void m1() {

我不知道为什么会出现这个错误,我只是做了这个网站所做的事情:source,但我的编译器一直坚持让我插入一个public static void main(String[] args){,即使我已经在底部插入了一个public static void main(String[] args){。我得到的唯一错误是public void m1(){上的illegal start of expression

【问题讨论】:

标签: java class interface


【解决方案1】:

“我是不是把原来的代码改的太多了?”

国际海事组织,是的。问题是“为了使该代码成功编译,C 类的代码必须是真的什么?”。那是在询问您应该如何更改 C 以使其编译。它没有提到更改I

这将是一个更好的答案:

public class C implements I {
    public void m1() {
         // do something
    }

    public void m2() {
         // do something else
    }
}

非代码(即英文)答案是C需要实现I声明的m1m2方法...具有相同的签名和兼容的返回类型和throws子句.

还有一些额外的警告。 IC 代码需要位于单独的文件中(因为两者都是顶级类型和 public)。这意味着他们每个人都应该在开头有一个package 声明。


FWIW,还有另一个答案:

public class C {}

删除implements IC 将编译。但我不认为这是提问者期望的答案。

【讨论】:

    【解决方案2】:

    我认为目标是仅更改 C 类而不是接口。 不做你的工作任务,只写代码: // C类代码

    【讨论】:

      【解决方案3】:

      当一个接口由一个类实现时,我们需要在实现的类中为接口中声明的方法提供实现。

      接口只提供方法的声明,这些方法的定义应该在实现的类中给出。

      我们可以为接口中的方法使用 default 关键字来提供实现而不是声明(可从 Java 8 获得)。在这种情况下,没有提供定义的方法应该在类C中实现

      根据问题——代码应该在 C 类中给出。 所以,改变接口方法并不是完美的答案。

      public class C implements I {
              public void m1(){
                  System.out.println("simply a method definition");
              }
              public void m2(){
                  System.out.println("simply a method definition");
              }
      
      
              }
      

      【讨论】:

      • 请注意,您并没有覆盖任何东西......您正在实现接口的方法。另外,我建议不要在这样的方法主体的末尾添加;。它不会导致错误,但会令人困惑。
      • @JonSkeet 我认为该措辞没有问题。 Java 8 Trail 调用此超类型方法的覆盖
      • @JonSkeet 为接口的方法提供实现可以称为覆盖。虽然为了更好地理解而改写了
      • @StephenFrancis:我强烈建议不要使用该术语,除非接口提供默认实现。 “覆盖”这个词给人的印象是提供了一个新的实现,而不是另一个实现......而这里的情况并非如此。
      • @JanezKuhar:看我对斯蒂芬的回复。我认为在没有默认实现的情况下,它会令人困惑,并且与该术语的正常含义不一致。
      【解决方案4】:

      让您的代码无需太多更改即可编译的理想方法是在类中覆盖接口的方法。另外,如果接口和类在单个文件中定义,请删除接口的访问修饰符。

      解决方案-

      interface I {
          public void m1();
          public void m2();
      }
      public class C implements I {
          // code for class C
          @Override
          public void m1() {}
      
          @Override
          public void m2() {}
      }
      

      或者,如果你想在接口中定义一个默认方法,你可以这样做 -

      interface I {
          public void m1();
          default public void m2() {
              System.out.println("default m2");
          }
      }
      public class C implements I {
          public void m1() {
              C c = new C();
              c.m2();
          }
      }
      

      【讨论】:

        【解决方案5】:

        一个字就能搞定。

        但首先:

        C c = new C();          
        c.m2();
        

        我不知道你为什么添加它或者它试图完成什么。我假设它是您不小心粘贴的剩余测试代码。但如果不是,这没有任何意义 - 只需摆脱它/解释它试图做什么。

        问题的本质是实现接口的类必须对接口中提到的每个方法都有一个实现。有很多方法可以解决这个问题:

        • 从接口中删除方法(只需删除 I 中声明方法的 2 行 - 瞧!
        • 在接口中为方法提供默认实现,这样就不需要实现接口的类来提供这些方法的实现——您或多或少已经做到了。不过,这可能是解决问题的最复杂方法!
        • 给出所述方法的类实现。
        • 只需将类抽象化 - 抽象类不必像通常那样为其继承的所有方法提供实现。

        最后一个是您“最简单”的答案。一字之差:

        public interface I {
            public void m1();
            public void m2();
        }
        
        public abstract class C implements I {}
        

        然而,这掩盖了这个问题的一个更核心的问题:

        这是一个愚蠢的问题!

        该问题明确指出:“C 类的代码必须是真实的” - 正如我在上面所展示的,这个问题没有一个答案。

        如果我们对提问者缺乏严谨性做出一些假设,我猜其意图是假设abstract 不作为一个概念存在,并且接口作为提供的是按原样处理,不能更改。在这种情况下,唯一正确的答案是 C 类需要实现这两种方法。因此,虽然有很多答案并且使 C 抽象是最简单的,但如果我查看我的水晶球并对问题作者(严重)试图在这里完成的问题做出一些假设,他们正在寻找这个:

        public interface I {
            public void m1();
            public void m2();
        }
        
        public class C implements I {
            @Override public void m1() {}
            @Override public void m2() {}
        }
        

        虽然不是必需的,但您也应该始终在这些方法上粘贴 @Override 注释,因此,@Override public void m1() {}。这是经过编译器检查的文档:如果您将该注释粘贴在实际上没有覆盖任何内容的方法上(例如,因为您打错了字),编译器会告诉您它,这很好。如果您愿意,可以将它们关闭(m1() {} 将覆盖该注释是否存在 - 该注释只是确保如果它没有覆盖任何内容,编译器将出错)。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-09-17
          • 1970-01-01
          • 2015-01-05
          • 1970-01-01
          • 1970-01-01
          • 2013-04-01
          • 1970-01-01
          • 2023-03-25
          相关资源
          最近更新 更多