一个接口有多个实现类时,调用接口时,如何判定调用的哪个实现类?
一个接口有多个实现类时,调用接口时,如何判定调用的哪个实现类?这里有三种方法解决
今天在学习依赖注入的时候,碰到这个问题:当一个接口有多个实现类的时候,我们调用方法的时候,通常是调用接口,而不是直接调用实现类。这是因为接口用来定义申明,而实现类可以是多种变化的,所以通常我们在调用时写接口,而不是具体的实现类,可以降低代码的耦合性,提高重用度。
以下是遵循接口编程的一些好处:
1. 松耦合(Loose Coupling):通过面向接口编程,调用方与实现方之间的依赖关系变得松散。调用方只需要知道接口的方法和约定,而不需要了解具体的实现细节。这样可以降低代码的耦合度,使系统更加灵活和可维护。
2. 可替换性(Replaceability):使用接口编程可以实现组件的可替换性。如果一个接口有多个实现类,你可以在不修改调用方代码的情况下,轻松地切换不同的实现类。这种可替换性对于系统的扩展性和测试性都非常有价值。
3. 单一职责原则(Single Responsibility Principle):接口可以将不同的功能和责任进行划分,每个实现类只需关注自己的具体实现。这样可以提高代码的可读性、可维护性和可测试性,使系统更加清晰和易于理解。
4. 接口抽象性(Interface Abstraction):接口可以提供一种抽象层次,隐藏实现类的内部细节。这样可以将关注点集中在接口定义和使用上,而不需要关心具体的实现细节。这种抽象性有助于提高代码的可理解性和可复用性。
那么当一个接口有多个实现类时,我们怎么知道调用哪个实现类呢?以下是几种常见的示例,展示如何实现接口并调用具体的实现类:
1、显式实例化调用:直接通过接口类引用实现类的对象
interface MyInterface {
void myMethod();
}
class MyClass1 implements MyInterface {
@Override
public void myMethod() {
System.out.println("MyClass1 implements MyInterface");
}
}
class MyClass2 implements MyInterface {
@Override
public void myMethod() {
System.out.println("MyClass2 implements MyInterface");
}
}
public class Main {
public static void main(String[] args) {
MyInterface obj1 = new MyClass1();
obj1.myMethod(); // 输出:"MyClass1 implements MyInterface"
MyInterface obj2 = new MyClass2();
obj2.myMethod(); // 输出:"MyClass2 implements MyInterface"
}
}
2、在配置文件中决定调用
interface MyInterface {
void myMethod();
}
class MyClass1 implements MyInterface {
@Override
public void myMethod() {
System.out.println("MyClass1 implements MyInterface");
}
}
class MyClass2 implements MyInterface {
@Override
public void myMethod() {
System.out.println("MyClass2 implements MyInterface");
}
}
public class Main {
public static void main(String[] args) {
String className = getConfiguredClassName(); // 从配置文件或属性文件获取类名
try {
Class<?> clazz = Class.forName(className);
MyInterface obj = (MyInterface) clazz.newInstance();
obj.myMethod();
} catch (ClassNotFoundException | InstantiationException | IllegalAccessException e) {
e.printStackTrace();
}
}
private static String getConfiguredClassName() {
// 从配置文件或属性文件读取要使用的类名
return "com.example.MyClass1";
}
}
3、通过依赖注入调用方法
interface MyInterface {
void myMethod();
}
class MyClass1 implements MyInterface {
@Override
public void myMethod() {
System.out.println("MyClass1 implements MyInterface");
}
}
class MyClass2 implements MyInterface {
@Override
public void myMethod() {
System.out.println("MyClass2 implements MyInterface");
}
}
@Component
class MyComponent {
@Autowired
private MyInterface obj;
public void performAction() {
obj.myMethod();
}
}
public class Main {
public static void main(String[] args) {
ApplicationContext context = new AnnotationConfigApplicationContext(AppConfig.class);
MyComponent component = context.getBean(MyComponent.class);
component.performAction(); // 根据依赖注入框架的配置,调用相应的实现类
}
}
@Configuration
@ComponentScan(basePackages = "com.example")
public class AppConfig {
// 配置依赖注入框架
}
更多推荐



所有评论(0)