理解类

时间:2009-07-21 13:27:38

标签: java

我是编程新手,对课程有一些疑问。

我将以卡雷尔为例:

public class Karel extends robot{
   ....

}

然后我延伸了Karel:

public class SuperKarel extends Karel{
   ....

}

但后来我想组织一些方法组:

public class KarelJumps extends SuperKarel {
    ....

}

public class KarelColor extends SuperKarel {
    ....

}

但是如果我想让Karel跳,我必须创建一个实例 KarelJumps而不是SuperKarel。但因为KarelJumps是一个 不同的对象然后KarelColor我不能使用它的任何方法。

所以我只需要放置所有KarelJumpsKarelColor方法 在SuperKarel?里面我只制作一个大型物体吗?

6 个答案:

答案 0 :(得分:4)

扩展类的最有用的原因是,您可以在新对象中使用基础类的功能,然后添加新类型特有的行为和特征。如果没有令人信服的理由这样做,并且经常没有,那么就不要这样做。不要过度复杂化您的设计,只是为了尝试利用多态和继承。

您希望使用这些技术使您的应用程序不那么复杂。对于一个新的程序员,我建议你得到“代码完整”一书,并将它作为你的圣经一段时间。你不会从中学到一门语言,但你将学习如何完成任务以及为什么要这样做。

答案 1 :(得分:2)

看起来你试图理解多态性而不是类。

继承不提供“方法分组”的机制。

经典继承和多态的核心概念可以方便地在Liskov Substitution Principle中捕获。从该维基页面被盗:

  

如果S是T的子类型,则程序中类型T的对象可以用类型S的对象替换,而不改变该程序的任何所需属性。

确保您的子类可以替代超类,并且除了添加一些重要的适当功能外,否则不要使用继承。

答案 2 :(得分:1)

如果您希望跳转Karel并且可以访问KarelColor方法,则需要将它们放在一个类中,或者更改层次结构。

KarelJumpsKarelColor是兄弟姐妹,无法访问彼此的方法。如果你真的想把它们分开,可能是:

public class SuperKarel extends Karel
public class KarelJumps extends SuperKarel
public class KarelColor extends KarelJumps

编辑:听听ChrisB的回答。如果您没有为每个扩展类添加重要功能,则可能应该避免使用层次结构。

答案 3 :(得分:1)

我认为你忽略了方法的概念。类是可以包含数据和定义方法的结构。为了执行操作,您不需要继续扩展原始类,您可以定义新方法。扩展Karel很好,只要有一个原因你需要在你的SuperKarel中做一些类似但与Karel不同的事情。

public class Karel extends robot{
    public void jump(){
    ...
    } 

   public void setColor(Color c) {
   ...
   }

}

public class SuperKarel extends Karel{
    public void jump(){
       //jump in a super way    
    } 

   public void setColor(Color c) {
       //set some super color 
   }
}

答案 4 :(得分:0)

每当你创建一个课时,问“它做了什么?”这些方法都在课堂上。

您需要首先从使用您的Karel的人的角度来看。

Here is myK he is a Karel

oh, I wonder what he can do ... hmmm looks like a Karel can jump

myK.jump(howHigh)

hey he jumped

wonder what else he can do ...

那个人不想要的是过多的不同对象myK,mySuperK,myColouredK做不同的工作。你给了他一个很好的连贯的完整的 Karel对象。

如果您觉得这会导致一个非常大的“Karel”课程,并且您想进一步组织,那么您可以分解Karel实现(想想轮子,笔等)来完成各种任务,但是从外面它是一个Karel

答案 5 :(得分:0)

有几种解决方案:

  1. 您可以在课程树中向上移动方法(如您所知)。

  2. 您可以使用接口声明常用方法。如果KarelJumpsKarelColor实现了接口,则某些代码可能会要求“实现此接口”。由于两个类都实现(满足)接口,因此代码将起作用。缺点:您必须在每个类中实现接口的方法(代码重复 - >坏)。

  3. Java不支持“mixins”,所以这不是一个选项,只是为了完整性:Mixins是编译器为您复制的代码片段。因此,您可以在一个地方维护代码,然后让编译器将所述代码复制到数千个地方(或使用任何其他技巧使其看起来像这样)。

  4. 您可以使用委托。然后委托实现该方法。在两个Karel类中,添加一个字段delegate并调用委托实现:

    interface IDelegate { void method (); }
    class Delegate implements IDelegate {
        void method () { ... }
    }
    
    public class KarelJumps extends SuperKarel implements IDelegate {
        IDelegate delegate = new Delegate ();
    
        // Instead of copying the code, delegate the work
        void method () { delegate.method (); }
    }