抽象与空方法
Abstract vs Empty method
我需要在现有摘要 class 中添加一个可选方法,该方法扩展了 50 多个 classes:
public abstract class Animal{...}
所有 classes 都没有使用此方法,但将来可能会使用。
我的 classes 之一的结构是:
public class Dog extends Animal {...}
最干净的方法是使用 abstract
方法,但它迫使我更改所有现有的 classes。
解决方法是在 abstract
class:
中创建 "empty" 方法
public String getString(Map<String, Object> params){
return "";
}
然后在 class 扩展抽象 class.
的 es 中需要时覆盖它
有没有更好的解决办法?
有一个 "empty" 方法很好。但是为了确保它会在真正需要的地方实现,请考虑从这个方法中默认抛出一个异常:
throw new UnsupportedOperationException();
java.util.AbstractList
class:
中使用了类似的方法
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
我不禁觉得你这里有一些 architectural/design 问题,但在不了解更多的情况下,我不能肯定地说。如果 50 个 class 将继承自 Animal
,但不是所有的都将使用此方法,那么我想知道它们是否真的应该继承一个共同的 class。也许您需要更高级别的 sub-classing...想想 Kingdom->Phylum->Sub-Phylum。但我的直觉告诉我这仍然不是你的正确答案。
退后一步 - 你想要完成什么?如果您将来要在这些 class 上实现此功能,那么您还必须更改代码以了解 use/expect。继承的要点是允许代码引用 object 的预期常见行为,而无需知道它引用的 object 是什么类型。在您的 getString()
示例中,您可能具有这样的功能:
public string SendMessage(Animal someAnimal) {
string message = someAnimal.getString();
// Send the message
}
你可以传给它一只狗、一只猫、一只鸭嘴兽——随便什么。该函数不关心,因为它可以从其基础 class.
查询消息
因此,当您说您的动物不会执行此消息时...这意味着您将有逻辑确保只有猫和狗会调用此函数,并且鸭嘴兽的处理方式不同(或者根本没有)。这样就违背了继承的意义
一种更现代的方法是使用接口建立 "has a" 关系而不是 "is a" 关系。一个平面可能有一个 IEngine
成员,但是特定类型的引擎可以设置为 run-time,或者由平面 class 本身设置,或者如果成员是可写的,则由应用程序设置。
public interface IEngine {
string getStatus();
string getMileage();
}
public class Cessna {
public IEngine _engine;
public Cessna() {
_engine = new PropellerEngine();
}
}
您也可以直接从该接口继承...不实现 IAnimalMessage 的动物将不会实现该功能。需要这样做的动物。缺点是每只动物都必须有自己的实现,但由于您的基础 class 目前有一个没有 body 的抽象函数,我假设这是一个 non-issue。使用这种方法,您可以确定 object 是否实现了接口:
IAnimalMessage animalMessage = myPlatypus as IAnimalMessage;
// If your playtpus doesn't implement IAnimalMessage,
// animalMessage will be null.
if (null != animalMessage) {
string message = animalMessage.getString();
}
public interface IAnimalMessage {
string getMessage();
}
public class Platypus : IAnimalMessage {
// Add this implementation when Platypus implements IAnimalMessage...
// Not needed before then
public string getMessage() {
return "I'm a cowboy, howdy, howdy, howdy!";
}
}
这可能是最接近您要求的我可以建议... class那些不需要消息的人在他们这样做之前不会实现该接口,但是代码可以很容易地实现检查接口是否实现并采取相应措施。
我可以提供更多 helpful/specific 想法,但我需要更好地理解您要解决的问题。
我需要在现有摘要 class 中添加一个可选方法,该方法扩展了 50 多个 classes:
public abstract class Animal{...}
所有 classes 都没有使用此方法,但将来可能会使用。
我的 classes 之一的结构是:
public class Dog extends Animal {...}
最干净的方法是使用 abstract
方法,但它迫使我更改所有现有的 classes。
解决方法是在 abstract
class:
public String getString(Map<String, Object> params){
return "";
}
然后在 class 扩展抽象 class.
的 es 中需要时覆盖它有没有更好的解决办法?
有一个 "empty" 方法很好。但是为了确保它会在真正需要的地方实现,请考虑从这个方法中默认抛出一个异常:
throw new UnsupportedOperationException();
java.util.AbstractList
class:
public E set(int index, E element) {
throw new UnsupportedOperationException();
}
我不禁觉得你这里有一些 architectural/design 问题,但在不了解更多的情况下,我不能肯定地说。如果 50 个 class 将继承自 Animal
,但不是所有的都将使用此方法,那么我想知道它们是否真的应该继承一个共同的 class。也许您需要更高级别的 sub-classing...想想 Kingdom->Phylum->Sub-Phylum。但我的直觉告诉我这仍然不是你的正确答案。
退后一步 - 你想要完成什么?如果您将来要在这些 class 上实现此功能,那么您还必须更改代码以了解 use/expect。继承的要点是允许代码引用 object 的预期常见行为,而无需知道它引用的 object 是什么类型。在您的 getString()
示例中,您可能具有这样的功能:
public string SendMessage(Animal someAnimal) {
string message = someAnimal.getString();
// Send the message
}
你可以传给它一只狗、一只猫、一只鸭嘴兽——随便什么。该函数不关心,因为它可以从其基础 class.
查询消息因此,当您说您的动物不会执行此消息时...这意味着您将有逻辑确保只有猫和狗会调用此函数,并且鸭嘴兽的处理方式不同(或者根本没有)。这样就违背了继承的意义
一种更现代的方法是使用接口建立 "has a" 关系而不是 "is a" 关系。一个平面可能有一个 IEngine
成员,但是特定类型的引擎可以设置为 run-time,或者由平面 class 本身设置,或者如果成员是可写的,则由应用程序设置。
public interface IEngine {
string getStatus();
string getMileage();
}
public class Cessna {
public IEngine _engine;
public Cessna() {
_engine = new PropellerEngine();
}
}
您也可以直接从该接口继承...不实现 IAnimalMessage 的动物将不会实现该功能。需要这样做的动物。缺点是每只动物都必须有自己的实现,但由于您的基础 class 目前有一个没有 body 的抽象函数,我假设这是一个 non-issue。使用这种方法,您可以确定 object 是否实现了接口:
IAnimalMessage animalMessage = myPlatypus as IAnimalMessage;
// If your playtpus doesn't implement IAnimalMessage,
// animalMessage will be null.
if (null != animalMessage) {
string message = animalMessage.getString();
}
public interface IAnimalMessage {
string getMessage();
}
public class Platypus : IAnimalMessage {
// Add this implementation when Platypus implements IAnimalMessage...
// Not needed before then
public string getMessage() {
return "I'm a cowboy, howdy, howdy, howdy!";
}
}
这可能是最接近您要求的我可以建议... class那些不需要消息的人在他们这样做之前不会实现该接口,但是代码可以很容易地实现检查接口是否实现并采取相应措施。
我可以提供更多 helpful/specific 想法,但我需要更好地理解您要解决的问题。