Jus*_*ong 7 java inheritance composition
我为一个问题设计了以下内容:
class Animal {
// ...
}
class Guppy extends Animal { ... }
class Pigeon extends Animal { ... }
class TailedAnimal extends Animal {
// ...
}
class Dog extends TailedAnimal { ... }
class Cat extends TailedAnimal { ... }
class HornedAnimal extends Animal {
// ...
}
class Ram extends HornedAnimal { ... }
public static void main(String[] args) {
Animal a = getSomeAnimal();
a.doSomething();
if (a instanceof TailedAnimal) {
// do something
}
if (a instanceof HornedAnimal) {
// do something else
}
}
Run Code Online (Sandbox Code Playgroud)
Animal,HornedAnimal和TailedAnimal主要用作数据模型.
由于Java不支持多重继承,因此我无法创建Rhinoceros,它是一种角和尾动物.在询问后,有人建议使用组合和界面.我想出了以下内容:
class Animal {
// ...
}
class Guppy extends Animal { ... }
class Pigeon extends Animal { ... }
class Ram extends Animal implements IHorned { ... }
class Cat extends Animal implements ITailed { ... }
class Dog extends Animal implements ITailed {
BasicTail t = new BasicTail();
public Object getTail() {
return t.getTail();
}
public void setTail(Object in) {
t.setTail(in);
}
}
interface ITailed {
public Object getTail();
public void setTail(Object in);
//...
}
class BasicTail implements ITailed {
Object myTail;
public Object getTail() { return myTail; }
public void setTail(Object t) { myTail = t; }
}
interface IHorned {
// getters and setters
}
public static void main(String[] args) {
Animal a = getSomeAnimal();
a.doSomething();
// how do I check if a is horned or tailed?
}
Run Code Online (Sandbox Code Playgroud)
我的界面有getter和setter.有什么方法可以避免这种情况吗?假设目前没有办法抽象Tails和Horns的行为,并且它们主要用作数据持有者.如何确定我的动物是有角还是长尾?
小智 8
我在这里建议策略模式.简而言之:
interface TailedAnimal {
void moveTail();
}
interface HornedAnimal {
void hitWithHorn();
}
class Rhinoceros() implements TailedAnimal, HornedAnimal {
private TailedAnimal tail; //Instantiate it somehow e.g. constructor, setter
private HornedAnimal horn; //Instantiate it somehow e.g. constructor, setter
public void moveTail() {
tail.moveTail();
}
public void hitWithHorn() {
horn.hitWithHorn();
}
}
Run Code Online (Sandbox Code Playgroud)
通过使用它,您可以在接口的具体实现中封装行为,并且可以轻松地为少数动物分享完全相同的行为,以及在运行时更改它.
我认为一般来说你必须避免设置器。如果可以,请使用不可变对象,并将其私有数据初始化到其构造函数中。
为了区分动物,我使用了另一种模式,即访客模式。它很冗长,但您不必直接测试您正在处理的动物。
public class Animals {
private Animals() {
}
interface Animal {
void accept(final AnimalProcessor visitor);
}
interface AnimalProcessor {
void visitTailed(final TailedAnimal tailedAnimal);
void visitHorned(final HornedAnimal hornedAnimal);
}
interface TailedAnimal extends Animal {
void moveTail();
}
interface HornedAnimal extends Animal {
void hitWithHorns();
}
static class Dog implements TailedAnimal {
public void moveTail() {
//To change body of implemented methods use File | Settings | File Templates.
}
public void accept(final AnimalProcessor visitor) {
visitor.visitTailed(this);
}
}
static class Cat implements TailedAnimal {
public void moveTail() {
//To change body of implemented methods use File | Settings | File Templates.
}
public void accept(final AnimalProcessor visitor) {
visitor.visitTailed(this);
}
}
static class Ram implements HornedAnimal {
public void hitWithHorns() {
//To change body of implemented methods use File | Settings | File Templates.
}
public void accept(final AnimalProcessor visitor) {
visitor.visitHorned(this);
}
}
static class Rhinoceros implements HornedAnimal, TailedAnimal {
public void hitWithHorns() {
//To change body of implemented methods use File | Settings | File Templates.
}
public void moveTail() {
//To change body of implemented methods use File | Settings | File Templates.
}
public void accept(final AnimalProcessor visitor) {
visitor.visitTailed(this);
visitor.visitHorned(this);
}
}
public static void main(String[] args) {
Collection<Animal> animals = new ArrayList<Animal>(Arrays.asList(new Dog(), new Cat(), new Rhinoceros()));
for (final Animal animal : animals) {
animal.accept(new AnimalProcessor() {
public void visitTailed(final TailedAnimal tailedAnimal) {
// you do what you want when it's a tailed animal
}
public void visitHorned(final HornedAnimal hornedAnimal) {
// you do what you want when it's a horned animal
}
});
}
}
}
Run Code Online (Sandbox Code Playgroud)