oco*_*mfd 2 java inheritance dry composition
考虑有一个简单的用例,一个带有具有共同属性的子类的父类,例如:类 Animal 有一个名称:
public class abstract Animal{
protected String name;
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
abstract void printInfo();
}
Run Code Online (Sandbox Code Playgroud)
和子类:
public class Cat extends Animal{
@Override
public void printInfo(){
System.out.println("I'm a cat");
}
}
public class Dog extends Animal{
@Override
public void printInfo(){
System.out.println("I'm a dog");
}
}
Run Code Online (Sandbox Code Playgroud)
根据优先组合而不是继承?和https://softwareengineering.stackexchange.com/questions/162643/why-is-clean-code-suggesting-avoiding-protected-variables,应该避免继承和受保护的变量,所以我将 Animal 修改为一个接口:
public interface Animal{
void setName(String name);
String getName();
void printInfo();
}
Run Code Online (Sandbox Code Playgroud)
但是在移动类属性时噩梦就来了:
public class Cat implements Animal{
private String name;
@Override
public void setName(String name){
this.name=name;
}
@Override
public String getName(){
return name;
}
@Override
public void printInfo(){
System.out.println("I'm a cat");
}
}
public class Dog implements Animal{
private String name;
@Override
public void setName(String name){
this.name=name;
}
@Override
public String getName(){
return name;
}
@Override
public void printInfo(){
System.out.println("I'm a dog");
}
}
Run Code Online (Sandbox Code Playgroud)
以下代码:
private String name;
@Override
public void setName(String name){
this.name=name;
}
@Override
public String getName(){
return name;
}
Run Code Online (Sandbox Code Playgroud)
需要复制并粘贴到每个类中。此外,如果还有一个属性要添加,例如:weight,我需要手动更新 Animal 和每个子类。
我的问题是,它是否违反了 DRY 原则?如果是这样,有没有什么方法可以重构原始代码,避免继承和保护变量,同时也遵守DRY原则,这样我就不需要将公共属性的代码复制粘贴到每个子类中?
(或者原来的已经没问题了?)
应避免继承和受保护的变量
继承很好,只要你不强迫用户在他们需要一个界面时使用它。Java的List<T>并AbstractList<T>提供了一个很好的例子:如果需要使用部分共享实现,继承抽象类;如果不这样做,请实现该接口。
protected String name也可以制作字段private,从而消除受保护变量的使用。
以下是该方法如何适用于您的类层次结构:
public interface Animal {
void setName(String name);
String getName();
void printInfo();
}
public abstract class AbstractAnimal implements Animal {
private String name;
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
abstract void printInfo();
}
public class Cat extends AbstractAnimal {
@Override
public void printInfo(){
System.out.println("I'm a cat");
}
}
public class Dog extends AbstractAnimal {
@Override
public void printInfo(){
System.out.println("I'm a dog");
}
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
1754 次 |
| 最近记录: |