带有Java接口和抽象类的oop属性继承
好的,所以我想找出最好的结构。我想知道在这些情况下,什么是最佳做法,以及总体上最有效的做法
问题
假设我正在创造一个小世界。这个世界由不同类型的鸟组成,所以我创建了一个鸟类,作为所有鸟的父类
public abstract class Bird {
//stuff all birds have in common
}
现在我想创造不同类型的鸟。让我们创建一个企鹅和鹅类,并让他们扩展鸟
public class Penguin extends Bird{
//penguin stuff
}
public class Goose extends Bird{
//goose stuff
}
到目前为止还不错,但现在是扳手。让我们给鸟儿飞翔的能力<出乎意料的是,并不是所有的鸟都会飞——比如企鹅!让我们来探讨我们的选择
在Bird类中创建一个fly方法是不可能的(不是所有的Bird都会飞)。另一种难闻的方式是有多个父类,比如BirdShatfly,因为这会变得非常混乱,尤其是当其他birdly属性被添加到组合中时
选项1
接口
从理论上讲,一个可行的选择听起来是正确的,那就是使用接口。例如,我可以有一个飞行界面
public interface Fly {
public void fly();
}
这将允许我实现只在能飞行的Bird子类上飞行。例如
public class Goose extends Bird implements Fly {
@Override
public void fly() {
//fly!
}
}
这看起来很干净,并强制在goose上使用fly方法,而且在添加其他属性时,它似乎可以很好地工作
似乎不对的是,我仍然需要为每种类型的鸟创建一个定制的苍蝇,而且可能会有很多鸟!默认的空隙能帮我吗?我觉得随着这些属性的增长,它们可能会受到相当大的限制
也许我可以被告知其他情况,以及如何重新思考这个接口结构
选择2
我自己的属性类
这涉及到创建属性对象并将它们添加到各个bird类中。如果我对接口的理解是正确的,那么这个选项可能是一种有效的方法
属性类看起来像这样
public abstract class Attribute {
public abstract void execute();
}
属性可以是这样的
public class Fly extends Attribute{
@Override
public void execute() {
//fly!
}
}
这个fly属性现在可以添加到bird中,方法是在bird中有一个属性列表,并将其填充到bird type类中
public abstract class Bird {
private List<Attribute> attributes = new ArrayList<Attribute>();
protected void addAttribute(Attribute attribute){
attributes.add(attribute);
}
public List<Attribute> getAttributes(){
return attributes;
}
}
把它加到鹅身上
public class Goose extends Bird{
public Goose(){
super.addAttribute(new Fly());
}
}
对我来说,这种方法似乎非常可定制,但也似乎不太实际,可能无法立即明确每个类都能做什么。它还需要大量工作才能在更大范围内正确设置,以便能够执行特定属性
有没有一种方法可以被认为是更好的实践,或者这是一种合理的方法还是一个良好的开端
# 1 楼答案
这只是关于面向对象设计的一些基本思想。如果没有更具体的信息,就很难对设计类或接口做出明确的决定
继承、行为和属性主要影响设计。设计的方式也取决于尺寸(数量、类型和种类)。我们可以看看Java语言本身的继承设计,例如集合
Collection
接口和Map
接口及其实现以下是一些即时的想法:
这种设计将允许:
Bird
接口中提供更多类似pluck()
的方法,并且只在AbstractBird
中实现李>AbstractBird
,并且 用更具体的实现直接实现Bird
接口 关于{WaterBirds
*李>*
并且可以为能够潜入水中捕鱼的鸟类和能够飞翔和滑翔的鸟类创建新的界面,比如
Diveable
。可以看出Glideable
是飞鸟的一种特殊行为。还要注意Glidable
也是HangGlider的一种行为,鸟和飞机都有这种行为注意:对于java 8,可以考虑使用静态
# 2 楼答案
如果所有的飞鸟都有相同的飞行方法,你可以使用多个层次的遗传
创建一个主
Bird
对象,处理所有鸟类都能做的动作。然后创建扩展Bird
的两个子类,比如FlyingBird
和GroundedBird
。这是一种更合适的方式来区分每种类型的Bird
的能力编辑
还有几个其他选项可以处理更多属性。OP还询问(在下面的评论中)如果鸟能飞和游泳怎么办
在继承链中的某个时刻,您将需要以任何一种方式实现该行为。如果您希望定义
Bird
的多个属性,则可以使用接口:现在,假设你想让所有的飞鸟都有相同的飞行动作。虽然不一定是想法,但您可以创建一个名为
BirdAction
的静态类来保存一只鸟可能会使用的所有“动词”您仍然需要为每个
Bird
重写fly()
方法,但让它们在BirdAction
内调用相同的静态方法:我不会说这是一个理想的解决方案,但取决于您的实际应用程序,它可能会起作用当然,默认情况下,
Penguin
不会有fly()
方法,但如果仍然从Penguin
类调用BirdAction.fly()
,则会进行检查