2014-03-05 223 views
2

我对接口和继承如何在实现阶段工作感到困惑。这里有一个快速的ERD:实现接口和继承

          <<interface>> 
Animal         IColorChangable  
----------------------------    ----------------------- 
-color: int        ----------------------- 
----------------------------    + changeColor() 
----------------------------    ----------------------- 
     ^(Inheritance Triangle)    ^(Interface Triangle) 
     |         | 
     |         | 
---------------------------------------------- 
Dog 
---------------------------- 
-breed: string 
---------------------------- 
+ getBreed() 
---------------------------- 

所以在这里我有一只狗延长动物类,并且还实现了一个ColorChangable接口。现在,colorchangeable界面的工作是更新颜色,这是属于动物的属性,而不是Dog。那么更新狗类颜色的正确方法是什么?它是实现变色的狗,而不是动物。现在,我有这样的:

public class Dog extends Animal implements IColorChangable 
{ 
    private String breed; 

    public Dog(int color, String breed) 
    { 
     super(color); 
     this.breed = breed; 
    } 

    public void changeColor() 
    { 
     //How to have access to color? 
    } 
} 

public interface IColorChangable 
{ 
    public void changeColor(); 
} 

回答

2

你基本上有三种选择。你的选择取决于你的需求,你的不变量的复杂性等

第一种方案是在Animal声明colorprotected,那么您可以在派生类直接访问:

public class Animal { 
    protected int color; 
    ... 
} 

public class Dog extends Animal implements IColorChangable { 
    ... 
    @Override public void changeColor() { 
     color = ...; 
    } 
} 

的第二种选择是在Animal中声明private,在这种情况下,您无法直接使用子类访问它,但可以根据您的规则向Animal(可选地final,可选protected)添加setter。如果,例如,你想实现在基类常见的验证逻辑,这非常有用:

public class Animal { 
    private int color; 
    ... 
    protected final void setColor (int color) { // could be public, could be non-final 
     this.color = color; 
    } 
} 

public class Dog extends Animal implements IColorChangable { 
    ... 
    @Override public void changeColor() { 
     setColor(...); 
    } 
} 

第三个选项是要考虑的问题是:能否动物的颜色改变? (在你的榜样,color是一般Animal的属性。)如果是这样,那么你可以有Animal实现接口来代替:

public class Animal implements IColorChangable { 
    private int color; 
    ... 
    @Override public void changeColor() { 
     color = ...; 
    } 
} 

public class Dog extends Animal { 
    ... 
} 

这真的取决于你需要做什么。

顺便说一句,它不是通常是传统在Java中启动接口名称与I就像它是在COM API中。另外我们通常使用“属性”而不是“属性”。:)

3

所以,你只需要为setColor和的getColor添加到您的动物类,但你应该将它们定义为一个公共方法。

public void setColor(int color){ 
    this.color = color; 
} 

public int getColor(){ 
    return color; 
} 

然后在changeColor方法中,您可以通过setColor填充颜色。

public void changeColor() 
{ 
    setColor(10); //for example 
} 
+1

非常真实,但不是问题? – KJ3

+0

对不起,我编辑了它。 –

+0

'setColor'和'getColor'不一定是'public',如果它更适合这种情况,它们可以被'保护'。另外值得注意的是,让吸气剂通常具有很大的意义,但它不是必需的。在更深层次上,如果'Animal'具有'color',则可能值得考虑如果'Animal'应该是实现'IColorChangable'的那个。 –

1
color = 123; 

但是你的属性颜色必须设置为公共的或受保护的。

如果是私人的,你需要做一个设置在动物类:

public void setColor(int color){ 
    this.color = color; 
} 

然后调用它在你的方法:

setColor(color); 
0

刚刚接触它作为普通的一员:

public void changeColor(int color) 
{ 
    this.color = color; 
} 
+1

由于OP没有显示'color'的访问级别,所以我们不知道这是否可能(可能是'private')。此外,建议使用'@ Override'标签来清楚说明(Eclipse,顺便说一下,如果缺失,会默认生成警告)。 –