假设我正在实现一个简单的接口,比如动物。一般来说,这样做有两种方法:
我想知道如果-
public interface Animal {
void makeSound();
}public abstract class BaseAnimal implements Animal {
@Override
public void makeSound() {
//do something which is common for all implementaions
doSomeImplementaionSpecificStuff();
}
public abstract void doSomeImplementaionSpecificStuff();
}
public class Dog extends BaseAnimal implements Animal {
public void doSomeImplementationSpecificStuff(){
//do something specific to a dog
}
}public abstract class BaseAnimal implements Animal {
public void doCommonStuff() {
//any common logic that can be shared between concrete implementation goes here
}
}
public class Dog extends BaseAnimal implements Animal {
@Override
public void makeSound() {
doCommonStuff();
//do something specific to a dog
}
}发布于 2019-09-01 12:19:56
这两种方式并不总是可以互换的。
第一个示例为需要实现作为makeSound()方法一部分的特定方法的子类设置一个约束。
通过这种方式,可以将父类之一的子类的实现强耦合到其中一个子类。
此外,子类仍然可以是子类makeSound(),因为它不是final。
因此,我只会在非常具体的场景中使用这种方法:
在一般情况下,您希望使用第二个示例的代码,但通过执行BaseAnimal也是一个Animal:
public abstract class BaseAnimal implements Animal {
public void doCommonStuff() {
//any common logic that can be shared between concrete implementation goes here
}
}
public class Dog extends BaseAnimal implements Animal {
@Override
public void makeSound() {
doCommonStuff();
//do something specific to a dog
}
}注意,在Java 8中,默认接口依赖于定义只定义公共方法的抽象类:
public interface Animal {
void makeSound();
default void doCommonStuff() {
//any common logic that can be shared between concrete implementation goes here
}还请注意,在抽象类的API中公开doCommonStuff()并不一定很好。客户应该能打电话吗?如果这是实现细节,您可以将其提取到支持类(AnimalDelegate)中,并通过将AnimalDelegate组合到Animal子类来支持组合而不是继承。
发布于 2019-09-01 12:04:32
主要区别在于,如果不希望实现父类/抽象类的所有方法,则可以将逻辑放在父类中,并创建一种默认方法。接口迫使您无论如何都要实现所有的方法。
public abstract class BaseAnimal {
public void doCommonStuff() {
System.out.println("doComon1");
}
public void doCommonStuff2() {
System.out.println("doComon1");
}
public static void main(String[] args) {
SuperDog superDog = new SuperDog();
superDog.doCommonStuff();
}
}两项执行可以是:
public class cat extends BaseAnimal {
@Override
public void doCommonStuff() {
//specific logic
}
@Override
public void doCommonStuff2() {
//specific logic
}
}
public class Dog extends BaseAnimal {
@Override
public void doCommonStuff() {
//specific logic
}
// don't override the doCommonStuff2() method so you have the parent implementation
}此外,对于抽象类,您可以混合使用:
public class SuperDog extends BaseAnimal {
@Override
public void doCommonStuff(){
super.doCommonStuff();
System.out.println("do specific after common stuff");
}
}最后一个,可以调用父逻辑,也可以添加特定的逻辑。有了接口,您就不能这样做。
发布于 2019-09-01 12:06:54
如果有一种默认的通用方法来实现大多数子类将使用的接口,那么只需在抽象类中这样实现overriden方法即可。任何需要它的子类都可以保持原样。任何需要它的子类都可以完全重写和重新实现它。任何想要使用默认实现但又向其添加一些内容的子类都可以重写,然后调用super.makeSound()作为实现的一部分。
不要忘记准确地记录默认实现是什么。
https://stackoverflow.com/questions/57745799
复制相似问题