【问题标题】:Implement multiple classes in the same interface in Java?在Java的同一个接口中实现多个类?
【发布时间】:2018-05-10 08:14:36
【问题描述】:

我有多个类,每个类都实现了多个不同的方法。现在问题陈述是我希望在另一个类文件中使用所有这些方法(可能大约 200 个这样的不同类文件/方法),其中所有不同的方法都来自上述类文件。

我想如果我实现了一个列出了所有这些不同方法的接口,那么我只需调用/导入/引用该单个接口并可以使用所有方法吗?但我被困住了,因为这个解决方案似乎不起作用。

与上述工作相反(即单个类实现 2 个接口:http://tutorials.jenkov.com/java/interfaces.html)。希望检查单个接口是否可以使用多个类,而无需声明接口内引用的每个类中的所有方法的开销?

作为一个例子:有没有什么方法可以在同一个接口中实现 2 个不同的类,而每个类都没有抽象类?好像这个类是抽象的,那么我无法在下面的示例“应用程序”类中使用它的方法:

Common commonClass = new ABC_FamilyGivenName();

如果 ABC_FamilyGivenName 类是抽象类,则不允许上述情况。

INTERFACE:

public interface Common {
    void ABC_GivenNames();
    void ABC_FamilyNames();
    void ABC_Gender();
    void ABC_BirthDay();
}



IMPLEMENTATION CLASSES:

public class ABC_FamilyGivenName extends Base implements Common {

    public void ABC_GivenNames(){
        // Implementation code
    }

    public void ABC_FamilyNames(){
        // Implementation code
    }
}

public class ABC_DOBGender extends Base implements Common {

    public void ABC_Gender(){
        // Implementation code
    }

    public void ABC_BirthDay(){
        // Implementation code
    }
}



USE IMPLEMENTED CLASS:
public class Application extends Base {

    Common commonClass = new ABC_FamilyGivenName();
    /* DO I NEED THIS? I THINK I DO, BUT CODE/JAVA SAYS I DO NOT
     * Common commonClass = new ABC_DOBGender();
     */

    public void ELP_C0050_PassportDetails(){
        commonClass.ABC_GivenNames();
        commonClass.ABC_FamilyNames();
        commonClass.ABC_DOB();
        commonClass.ABC_Gender();
    }
}

我有 2 个名为 ABC_FamilyGivenName 和 ABC_DOBGender 的课程。 我已经创建了一个接口 Common。

我想在另一个名为 Application 的类中使用上述两个类中的方法。

在当前的实现中,Java 希望我在 ABC_FamilyGivenName 和 ABC_DOBGender 中都添加一个 @Override:

IMPLEMENTATION CLASSES:

public class ABC_FamilyGivenName extends Base implements Common {

    public void ABC_GivenNames(){
        // Implementation code
    }

    public void ABC_FamilyNames(){
        // Implementation code
    }

    @Override
    public void ABC_BirthDay() {}

    @Override
    public void ABC_Gender() {} 
}

public class ABC_DOBGender extends Base implements Common {

    public void ABC_Gender(){
        // Implementation code
    }

    public void ABC_BirthDay(){
        // Implementation code
    }

    @Override
    public void ABC_GivenName() { }     

    @Override
    public void ABC_FamilyName() { }        
}

我可以避免上述@Override 并且只使用第一个示例中给出的没有这些的类吗?

【问题讨论】:

  • 不,你不能。正确的方法可能是将您的界面分成两个单独的界面,并使用您确实需要的方法。
  • 如果您使用的是 java 8,请将所有方法设为默认方法,并在子类上覆盖所需的方法。
  • @SomeJavaGuy 我不希望有多个接口,因为这违背了目的,我宁愿直接使用该类。对我来说,我有大约 200 个这样的类,每个“应用程序”类型的类每次都会使用大约 20-30 个。我希望避免为我使用的每个类尝试导入/声明语句的开销,并希望使用一个;我认为可以通过使用界面来实现,但似乎并非如此。
  • @Saran 你能解释一下吗?
  • 也可以在以下位置找到解决方案:stackoverflow.com/questions/47523700/…

标签: java class interface overriding


【解决方案1】:

Java 中的面向对象编程需要“覆盖”所有方法,如果您正在实现一个方法,否则您可能会使用继承,因此并非所有方法都必须被覆盖。

在您的情况下,您可以将所有四个方法都放在父类 Base 中,然后继承它们。 那么接口类就不需要了,或者做两个不同的接口。

【讨论】:

    【解决方案2】:

    要实现Java接口,你应该重写所有在接口中声明的抽象方法。它是接口的一个基本概念。这里interface Common 四个方法都是抽象的,所以你应该重写它们。否则,Java 编译器会抛出编译错误。所以更好的方法可以将界面分成两部分。 这是接口的契约性质,实现接口的子类应该拥有接口的所有活动。这是使用接口的主要目的。

    如果不想重写接口的所有方法,但又需要将接口作为每个类的引用,那么可以使用具体类代替接口,并将具体类继承给每个类

    【讨论】:

    • 好的,这很好,我意识到了。但我的问题是,我实现了多个此类文件,我需要在“应用程序”类和其他此类文件中引用/使用它们。我不希望每次都在“Application”等中为每个类创建一个 new() 对象,只是为了使用该类的方法。
    • 您可以使用名为 common 的具体类来代替接口。然后将公共类继承到所有类。那么公共类可以作为每个类的引用
    • 感谢您的建议。可以举个例子吗?
    • 这里使用你的通用接口作为一个具体的类。然后编写所有方法的基本声明。如果任何类覆盖该方法,则实例调用被覆盖的方法。否则,它调用基本方法。但这里有一个问题。您不能在一个类中同时扩展基类和公共类。在这种情况下,通过基类扩展公共类,然后通过 ABC_FamilyGivenName 类扩展基类。希望对您有所帮助。
    【解决方案3】:

    要实现以下代码更改,请确保使用 java8

    public interface Common {
    
     default public void ABC_GivenNames() {
     }
    
     default public void ABC_FamilyNames() {
     }
    
     default public void ABC_Gender() {
     }
    
     default public void ABC_BirthDay() {
     }
    
    }
    

    实现类:

    public class ABC_FamilyGivenName extends Base implements Common {
    
        public void ABC_GivenNames(){
            // Implementation code
        }
    
        public void ABC_FamilyNames(){
            // Implementation code
        }
    
    }
    
    public class ABC_DOBGender extends Base implements Common {
    
        public void ABC_Gender(){
            // Implementation code
        }
    
        public void ABC_BirthDay(){
            // Implementation code
        }
    
    }
    

    【讨论】:

    • 感谢萨兰,以上工作。唯一的问题是被调用的方法没有实例化。
    • 您能解释一下这里的实例化是什么意思吗?
    • 如果我们在代码中使用该方法,它不会被引用或为该方法运行的实现。我们正在尝试调试并找出问题所在,因为没有编译时问题。
    • 使用此链接下载代码,使用支持 java 8 [github.com/saravananshivaji/TestDefaultMethods].有两种方法 1. 在接口中使用默认值,2. 使用适配器模式(这有一个名为 adapter 的包,您可以在其中使用 Base 类作为适配器)。
    【解决方案4】:

    我可以避免上面的@Override 并且只使用没有这些的类吗 和第一个例子一样吗?

    不,在java中你必须实现接口的所有方法,除非它的抽象类

    建议您可以创建两个单独的接口,

    更多详情见:not implementing all of the methods of interface. is it possible?

    【讨论】:

    • 如果我创建一个抽象类,则不允许在“应用程序”类中使用。是否有一种解决方法可以将它们实现为抽象类,然后可以通过“应用程序”类中的接口使用这些方法?基本上,如何在“Application”类中使用ABC_*类的方法?
    【解决方案5】:

    您可以为另一个名为 Adapter 的类中的接口的所有方法提供一个空实现。您可以在ABC_FamilyGivenName 类和ABC_DOBGender 类中扩展该适配器类。

    class Adaptor implements common
    {
    public void ABC_GivenNames() {
     }
    
     public void ABC_FamilyNames() {
     }
    
     public void ABC_Gender() {
     }
    
     public void ABC_BirthDay() {
     }
    }
    

    实现类

            public class ABC_FamilyGivenName extends Adaptor{
    
                public void ABC_GivenNames(){
                    // Implementation code
                }
    
                public void ABC_FamilyNames(){
                    // Implementation code
                }
    
            }
    
            public class ABC_DOBGender extends Adaptor {
    
                public void ABC_Gender(){
                    // Implementation code
                }
    
                public void ABC_BirthDay(){
                    // Implementation code
                }
    
            }
    

    【讨论】:

      【解决方案6】:
      interface Icalculate{                 //interface
      calculate(operand1:number,operand2:number):number
      }
      
      class Add implements Icalculate{     //addition
      calculate(operand1: number, operand2: number): number{
       return (operand1 + operand2);       
          }
      }
      
       class Sub implements Icalculate{       //subtraction
       calculate(operand1: number, operand2: number): number{
          return (operand1 - operand2);
        }
       }
      
      class Mul implements Icalculate{           //multiplicationn
      calculate(operand1: number, operand2: number): number{
          return(operand1*operand2);
       }
      }
      
       class Div implements Icalculate{         //Division
        calculate(operand1: number, operand2: number): number{
          return(operand1/operand2);
         }
      }  
        let a = new Add;
        let b = new Sub;
        let c = new Mul;
        let d = new Div;
      
        class Calculator {                   //main class
          operator: Icalculate;
          operand1: number;
          operand2: number;
          constructor(a: number, b: number, operator: Icalculate) {
          this.operand1 = a;
          this.operand2 = b;
          this.operator = operator;
          let op = this.operator;
          console.log(op.calculate(this.operand1, this.operand2));
          }
      }   
      const cal=new Calculator(1,1,a);
      

      【讨论】:

      • 请始终将您的答案放在上下文中,而不仅仅是粘贴代码。有关详细信息,请参阅here
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-07-08
      • 2014-01-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多