使用继承(使用抽象类)为子类提供自定义框架中的方法子部分的更优雅的方式?
More elegant way using inheritance (with abstract classes) to provide subclasses with a subsection of methods within a custom framework?
我有以下示例设置:
不幸的是,这行不通,我找不到合适、优雅的解决方法。
这个想法是,当添加一个新的动物类别(例如鸟类)时,我只创建一个类似于 TemplateMammals 的 TemplateBird。创建新鸟 class 时,我将只能访问通过 class BirdStuff.
定义的正确方法
我可以在动物类别模板中创建一个 non-abstract 方法(例如
public MammalStuff getAnimalStuff{ return new MammalStuff()}
for TemplateMammals) 但我不喜欢这样,因为我想创建一个框架,因此想强制用户实现这样的方法。
你有什么优雅的改进想法吗?或者完全不同的想法?
谢谢!
您可以使用仅限于 AnimalStuff 的泛型。
public class Dog : TemplateMammals
{
public void SomethingWhereINeedStuff()
{
var stuff = GetAnimalStuff();
// stuff is of type MammalsStuff
}
}
public class TempalteMammals : TemplateAnimals<MammalsStuff>
{
public abstract MammalsStuff GetAnimalStuff() { ... }
}
public class TemplateAnimals<TStuff> where TStuff : AnimalStuff
{
public abstract TStuff GetAnimalStuff();
}
使用泛型怎么样?
动物素材
第一步,我们将定义内容,Stuff
必须派生自基数 Interface
或 Abstract class
:
public interface AnimalStuff{
public void doAnimal();
}
然后您将根据需要定义层次结构。我混合了抽象 classes 和接口,但你可以做完整的抽象 classes 或完整的接口,直到实现 classes:
public abstract class MammalStuff implements AnimalStuff{
// no need to override unless there are mammal specific stuff
public void doAnimal(){...}
}
public abstract class BirdStuff implements AnimalStuff{
// example of bird specific
@Override
public void doAnimal(){
System.out.println("I believe I can fly!!!");
}
}
如果我以鸟为例:
public class EagleStuff extends BirdStuff{
@Override
public void doAnimal(){
super.doAnimal();
System.out.println("But I also eat preys!!!");
}
}
动物classes
然后您可以创建您的动物层次结构:
public abstract class TemplateAnimal<S extends AnimalStuff> {
public abstract S getAnimalStuff();
}
使用您定义的层次结构。泛型定义在这里有效 因为 MammalStuff
和 BirdStuff
扩展(或实现)AnimalStuff
public abstract class TemplateMammal<S extends MammalStuff> extends TemplateAnimal<S>{
// no overriding here
// public abstract S getAnimalStuff();
}
public abstract class TemplateBird<S extends BirdStuff> extends TemplateAnimal<S>{
// no overriding here
// public abstract S getAnimalStuff();
}
然后,您将拥有您的鹰:
public class Eagle extends TemplateBird<EagleStuff>{
@Override
public EagleStuff getAnimalStuff(){
// return ...
}
}
在 Eagle
class 中,如果 getAnimalStuff()
带有此签名 public AnimalStuff getAnimalStuff()
,这是非法的,因为泛型需要 return S
类型,而不是 AnimalStuff
我有以下示例设置:
不幸的是,这行不通,我找不到合适、优雅的解决方法。 这个想法是,当添加一个新的动物类别(例如鸟类)时,我只创建一个类似于 TemplateMammals 的 TemplateBird。创建新鸟 class 时,我将只能访问通过 class BirdStuff.
定义的正确方法我可以在动物类别模板中创建一个 non-abstract 方法(例如
public MammalStuff getAnimalStuff{ return new MammalStuff()}
for TemplateMammals) 但我不喜欢这样,因为我想创建一个框架,因此想强制用户实现这样的方法。
你有什么优雅的改进想法吗?或者完全不同的想法?
谢谢!
您可以使用仅限于 AnimalStuff 的泛型。
public class Dog : TemplateMammals
{
public void SomethingWhereINeedStuff()
{
var stuff = GetAnimalStuff();
// stuff is of type MammalsStuff
}
}
public class TempalteMammals : TemplateAnimals<MammalsStuff>
{
public abstract MammalsStuff GetAnimalStuff() { ... }
}
public class TemplateAnimals<TStuff> where TStuff : AnimalStuff
{
public abstract TStuff GetAnimalStuff();
}
使用泛型怎么样?
动物素材
第一步,我们将定义内容,Stuff
必须派生自基数 Interface
或 Abstract class
:
public interface AnimalStuff{
public void doAnimal();
}
然后您将根据需要定义层次结构。我混合了抽象 classes 和接口,但你可以做完整的抽象 classes 或完整的接口,直到实现 classes:
public abstract class MammalStuff implements AnimalStuff{
// no need to override unless there are mammal specific stuff
public void doAnimal(){...}
}
public abstract class BirdStuff implements AnimalStuff{
// example of bird specific
@Override
public void doAnimal(){
System.out.println("I believe I can fly!!!");
}
}
如果我以鸟为例:
public class EagleStuff extends BirdStuff{
@Override
public void doAnimal(){
super.doAnimal();
System.out.println("But I also eat preys!!!");
}
}
动物classes
然后您可以创建您的动物层次结构:
public abstract class TemplateAnimal<S extends AnimalStuff> {
public abstract S getAnimalStuff();
}
使用您定义的层次结构。泛型定义在这里有效 因为 MammalStuff
和 BirdStuff
扩展(或实现)AnimalStuff
public abstract class TemplateMammal<S extends MammalStuff> extends TemplateAnimal<S>{
// no overriding here
// public abstract S getAnimalStuff();
}
public abstract class TemplateBird<S extends BirdStuff> extends TemplateAnimal<S>{
// no overriding here
// public abstract S getAnimalStuff();
}
然后,您将拥有您的鹰:
public class Eagle extends TemplateBird<EagleStuff>{
@Override
public EagleStuff getAnimalStuff(){
// return ...
}
}
在 Eagle
class 中,如果 getAnimalStuff()
带有此签名 public AnimalStuff getAnimalStuff()
,这是非法的,因为泛型需要 return S
类型,而不是 AnimalStuff