这是一个关于应该使用继承方式的简单问题 .
考虑到我必须提供业务逻辑来打印'foo'和'bar'并且我有两个类的层次结构:一个具有仅打印'foo'的方法和另一个首先扩展并具有打印'bar'的方法 . 在这两个类中,我有一个名为 necessaryMethod()
的方法,负责调用那些打印'foo'和'bar'的方法 .
我用两种方法实现它的方式:
第一种方法是让基类做一些事情,派生类利用它 . 第二种方法是让基类不做任何事情(只提供实现)并将所有责任放在派生类上 .
请考虑以下代码:
Approach 1:
public class A{
protected void necessaryMethod(){
callFoo();
}
protected void callFoo(){
System.out.pritln("foo");
}
}
public class B extends A{
@Override
protected void necessaryMethod(){
super.necessaryMethod();
callBar();
}
protected void callBar(){
System.out.println("bar");
}
}
public class FooBarClass{
public static void main(String args[]){
B b = new B();
b.necessaryMethod();
}
}
Approach 2:
public abstract class A{
protected abstract void necessaryMethod();
protected void callFoo(){
System.out.pritln("foo");
}
}
public class B extends A{
@Override
protected void necessaryMethod(){
calFoo();
callBar();
}
protected void callBar(){
System.out.println("bar");
}
}
public class FooBarClass{
public static void main(String args[]){
B b = new B();
b.necessaryMethod();
}
}
哪种方法对于代码的可维护性和可读性是很好的(在大型软件产品/大类层次结构的上下文中;这只是一个例子)?
(这是一个通用的编程问题 . 我没有征求意见 . )
2 回答
暂时离开编程的技术方面,某些行为(其方法)有助于定义它 . 即一只狗吠() .
一般问题是:
1.1 . 在定义类时,在编程之外的类中组织方法(行为) .
Large Code Bases
尽管B可能属于现实世界中A的集合,但有时过多的继承可能会导致代码导航和维护 . 继承的目的更重要,实现继承本身并且不使用继承的调用可能更好 .
我在一年前实现了一个庞大的代码库,为它背后的复杂UML感到自豪,但最近重新审视它是一场噩梦 . 在某些地方,我可以使用更多的自由裁量权来选择使用继承 .
这个上下文中的问题是:这个继承是否有助于组织代码?它会帮助另一个程序员吗?
Abstract Classes
在程序中的任何一点实例化超类的实例,代替其中一个子类是否有意义?如果没有,则抽象超类获得投票 .
如果要使用派生类但将它们作为基类进行掩码,则基类应该具有派生类的所有功能(因为您告诉对象“认为”它是A而忘记它是B) . 所以在我看来,最好的方法是:
然后将B称为A,如下所示:
我认为这是非常可维护的,因为一旦你创建了基类,你就可以灵活地使用派生类做什么,而你的派生类与基类相比,你总是领先一步 . 除非你涉足过度继承,这总是很糟糕 . 总是尝试只有1级继承,偶尔有两次 . 任何其他东西都会迅速失控,如果你需要那么多的继承,那么评估接口是不是更好的选择可能是个好主意 .