【问题标题】:Identifying the relationship between interface and inheritance of different classes in Java识别Java中不同类的接口和继承关系
【发布时间】:2018-12-24 12:13:09
【问题描述】:

我正在尝试找出以下编码中的所有错误。有4个班,

  • A:接口
  • AImpl:实现 A 的类
  • B:C 的父类
  • C:B 的子类

    public interface A { 
       public void doSomeProcess(String s); 
    }  
    
    public class AImpl implements A { 
       public void doSomeProcess(String s) { 
           System.out.println("A Imple Code"); 
           [. . .] 
       } 
    } 
    
    public class B { 
        public A doIt() { 
           [. . .] 
        } 
        public String execute() { 
           [. . .] 
        } 
    } 
    
    public class C extends B { 
       public AImpl doIt() { 
           [. . .] 
       } 
       public Object execute() { 
           [. . .] 
       } 
    } 
    

这是我的理解,

  1. A 和 AImpl 都可以,因为 A 是一个接口类,而 AImpl 必须在 A 中实现抽象方法才能履行合同。
  2. C 类应从 B 类扩展public class B extends C
  3. C 类中的execute() 是覆盖方法

问题是我应该如何处理public A doIt()public AImpl doIt()?接口类可以是返回值吗?

谢谢!

【问题讨论】:

  • 覆盖方法doit()返回被覆盖方法返回的类的子类是完全可以的。这是一种众所周知的模式,称为“返回型协方差”。见stackoverflow.com/questions/10134571/…。但是,doit() 没有必要返回一个具体的类,因为它可以返回一个接口。
  • 返回类型在覆盖方法中可以更具体,但不能加宽(您可以使用子类型,但不能使用超类型)。所以 AImpl doIt() 在 C 中很好,但 Object execute() 不是。假设你有B b = new C()。当我们调用b.doIt() 时,我们希望得到类的some 对象,该对象在某些时候实现A,所以如果C 将返回AImpl,这是可以接受的。但是对于b.execute(),我们希望得到String。如果C 将覆盖它以允许 any Object 它还可以返回不能存储在 String 中的 Integer、Animal、Car,因此它会在 String s = b.execute(); 处中断。
  • 感谢@Pshemo 的明确解释!现在我明白了:)

标签: java inheritance interface


【解决方案1】:

Java 中没有术语“接口类”。它应该是一个接口或一个类。

是的,接口可以是返回类型。在这样的用例中可以看到多态性的好处。

【讨论】:

    【解决方案2】:

    是的,我们可以有一个返回类型为interface type

    例如:

    interface Bounceable
    { 
        Bounceable isBouncing();
    }
    
    Class Tyre implements Bounceable
    {
    
      @Override
      Bounceable isBouncing()
      {
         Bounceable myVariable;
    
         //your code 
    
         return myVariable;
      }
    
    }
    

    【讨论】:

    • 按照几乎通用的约定,名称以 is 开头的方法应该返回boolean
    • 是的,以后的答案会记住它
    【解决方案3】:

    问题是我应该如何处理public A doIt() 和public AImpl doIt()?接口类可以是返回值吗?

    没有任何问题YES,从 1.5 版本开始,协变返回类型被允许覆盖,即如果子类覆盖父方法,则方法返回类型不必与父方法返回类型,它也可以是它的子类型。 在您的情况下,子方法的doIt() 可以返回A 类型或子AImpl

    【讨论】:

      【解决方案4】:

      接口的一个主要方面是在任何地方都可以使用它们。只是因为某些方法的调用者不需要知道具体的实现类。

      假设您的方法确实返回 List。大多数时候,这完全没问题。调用者无需担心该方法是否返回 ArrayList 或 LinkedList 或任何列表!

      所以返回 A 完全没问题,应该优先使用它!

      【讨论】:

        【解决方案5】:

        是的接口类型,您可以将其用作返回类型(它可以保存对直接或间接实现该接口的任何类的对象的引用)

        在您的情况下,当您在 C 类中覆盖 doIt() 方法时,它是协变返回类型。 (因为 C 类中重写的 doIt() 方法的返回类型可以向上转换为 B 类中 doIt() 方法的返回类型。这是允许的)AImpl 可以向上转换为 A,因为 AImpl 是 A 的子级。

        【讨论】:

          猜你喜欢
          • 2012-06-25
          • 2023-03-19
          • 1970-01-01
          • 2019-07-16
          • 2021-11-18
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-08-23
          相关资源
          最近更新 更多