2015-11-08 43 views
3

这是一个关于继承应该如何使用的简单问题。继承:使用基类或派生类来做东西

考虑到我必须提供业务逻辑来打印'foo'和'bar',并且我有两个类的层次结构:一个只有'foo'打印方法,另一个先打印'并且有方法打印'酒吧'。 在这两个类中,我都有一个名为necessaryMethod()的方法,它负责调用打印'foo'和'bar'的方法。

的方式我实现它在两种方法:

第一种方法是让基类做一些东西和派生类利用它的优势。第二种方法是让基类不做任何事情(只提供实现)并将所有责任都放在派生类上。

考虑下面的代码:

方法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(); 
    } 
} 

方法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(); 
    } 
} 

哪种方法将是可维护性和代码的可读性(不错在大型软件产品/大类层次结构的背景下;这一点只是一个例子)?

(这是一个通用的编程问题,我并没有要求的意见。)

+1

这个问题在http://codereview.stackexchange.com/上更合适。 – jaco0646

+0

@ jaco0646如何迁移问题? –

回答

1

如果要使用派生类,但掩盖他们作为基类,基类应该有派生类中的每一个功能(因为你告诉物体“认为”它是A而忘记它是B)。所以,在我看来,最好的办法是:

public abstract class A{ 
    protected abstract void callBar(); 
    protected abstract void callFooBar(); 
    protected void callFoo() { 
     System.out.pritln("foo"); 
    } 
} 

public class B extends A { 
@Override 
    protected void callBar(){ 
    System.out.println("bar") 
    } 
@Override 
    protected void callFooBar(){ 
    callFoo(); 
    callBar(); 
    } 
} 

然后调用B,为这样的:

A b = new B(); 
b.callFooBar(); 

我认为这是相当维护,因为一旦你创建的基类,你是非常灵活用派生类可以做什么,并且与基类相比,你总是比派生类提前一步。除非你尝试过度休息,这总是不好的。总是尝试只有一级继承,偶尔两个。其他任何事情都会很快失去控制,如果你需要这么多继承,那么评估接口是不是更好的选择可能是个好主意。

2

远离编程的技术方面,某种行为(它的方法)有助于定义它。即狗吠()。

一般的问题是:

  1. 是否行为callFoo()让你觉得一个 'A'(A类),或 'B' 的?

1.1。在他们将属于编程之外的类中组织方法(行为) - 定义类。

大型代码库

即使B的可能属于在现实世界中的集合A的,有时太多的继承可以对着干导航和维护代码。继承的目的更重要,实现继承本身并且不要使用继承可能会更好。

我在一年前实现了一个庞大的代码库,对它背后的复杂UML感到非常自豪,但最近重新访问它是一场噩梦。在某些地方,我可以选择使用继承或不使用更多的自由裁量权。

在这种情况下的问题是:这种继承有助于组织代码吗?它会帮助另一位程序员吗?

抽象类

是否有意义在你的程序中的任何一点来实例化超类的实例,代替它的子类之一?如果不是,那么抽象超类获得投票。

+0

+1是关于实施的责任而不是技术约束。对GRASP的引用可能有用:https://en.wikipedia.org/wiki/GRASP_(objectject-oriented_design) – Guillaume

相关问题