Java中的隐式(继承对象)更合适吗?
我觉得使用父变量有点不合时宜。它必须是一种在子类中强制可见性的方法,以使其更显式Java中的隐式(继承对象)更合适吗?,java,spring,inheritance,junit,polymorphism,Java,Spring,Inheritance,Junit,Polymorphism,我觉得使用父变量有点不合时宜。它必须是一种在子类中强制可见性的方法,以使其更显式 public abstract class MyClass{ @Autowired Object implicitObject; @Test public void commonTest(){ implicitObject.doSomethingBasic(); } } public class MySubClass extends MyClass{ @
public abstract class MyClass{
@Autowired
Object implicitObject;
@Test
public void commonTest(){
implicitObject.doSomethingBasic();
}
}
public class MySubClass extends MyClass{
@Test
public void testSomethingElse(){
implicitObject.doSomethingElse();
}
}
你认为这是一个受人尊敬的模式吗?有什么最佳的选择吗?好吧,你可以通过添加这个来明确它
this.implicitObject.doSomething();
没有比这更好的了。可见性已经尽可能地“强制”(因为变量显然在子对象中可见)
关于继承字段的“开发人员如何看待可见性”的任何其他问题都会涉及IDE显示此类字段的方式(例如在Eclipse中,它们与Child完全相同,Intellij将它们显示为继承字段等)您可以通过添加此项来解释
this.implicitObject.doSomething();
没有比这更好的了。可见性已经尽可能地“强制”(因为变量显然在子对象中可见)
关于继承字段的“开发人员如何看待可见性”的任何其他事项都会涉及IDE显示此类字段的方式(例如在Eclipse中,它们与Child完全相同,Intellij将它们显示为继承字段等)保护字段 公开父类成员通常不是一个好主意,除非该字段被声明为final(这通常是不可能的),否则它可能会被损坏或被子类损坏。 最好用getter方法来保护它。虽然它确实使隐式对象更“可见”,但它受到保护,不受“恶意”子类的影响
public class MyClass{
@Autowired
private Object implicitObject;
public final Object implicitObject() {return implicitObject;}
}
public class MySubClass extends MyClass{
public void doSomething(){
implicitObject().doSomething();
}
}
这是个好习惯吗
是的,但这取决于隐式对象背后的内容,如果它是某种上下文或资源,API对我来说听起来会很好
通过访客界面控制访问 如果您想添加更多的“约束”,还有另一种解决方案:将隐式对象作为方法参数公开,这会增加隐式对象的“可见性”,但会涉及更多样板代码。(灵感来自访客模式) CustomTest是访问隐式对象的唯一方法:
public class MyCustomTest implements CustomTest {
@Override
public void test(Object implicitObject) {
implicitObject.doSpecificThing();
}
}
然后使用访问者实现
public class MySubClass extends MyClass{
@Test
public void testSomethingElse(){
super.customTest(new MyCustomTest());
}
}
太冗长了。。。这值得付出努力吗?同样,这取决于隐式对象背后的内容
使用您的容器 我不知道使用Spring是否可行,但是一些容器应该能够将隐式对象作为方法参数注入
public abstract class MyClass{
@Autowired
Object implicitObject;
@Test
public void commonTest(){
implicitObject.doSomethingBasic();
}
}
public class MySubClass extends MyClass{
@Test
@Autowired
public void testSomethingElse(Object injectedImplicitObject) {
injectedImplicitObject.doSomethingElse();
}
}
保护字段 公开父类成员通常不是一个好主意,除非该字段被声明为final(这通常是不可能的),否则它可能会被损坏或被子类损坏。 最好用getter方法来保护它。虽然它确实使隐式对象更“可见”,但它受到保护,不受“恶意”子类的影响
public class MyClass{
@Autowired
private Object implicitObject;
public final Object implicitObject() {return implicitObject;}
}
public class MySubClass extends MyClass{
public void doSomething(){
implicitObject().doSomething();
}
}
这是个好习惯吗
是的,但这取决于隐式对象背后的内容,如果它是某种上下文或资源,API对我来说听起来会很好
通过访客界面控制访问 如果您想添加更多的“约束”,还有另一种解决方案:将隐式对象作为方法参数公开,这会增加隐式对象的“可见性”,但会涉及更多样板代码。(灵感来自访客模式) CustomTest是访问隐式对象的唯一方法:
public class MyCustomTest implements CustomTest {
@Override
public void test(Object implicitObject) {
implicitObject.doSpecificThing();
}
}
然后使用访问者实现
public class MySubClass extends MyClass{
@Test
public void testSomethingElse(){
super.customTest(new MyCustomTest());
}
}
太冗长了。。。这值得付出努力吗?同样,这取决于隐式对象背后的内容
使用您的容器 我不知道使用Spring是否可行,但是一些容器应该能够将隐式对象作为方法参数注入
public abstract class MyClass{
@Autowired
Object implicitObject;
@Test
public void commonTest(){
implicitObject.doSomethingBasic();
}
}
public class MySubClass extends MyClass{
@Test
@Autowired
public void testSomethingElse(Object injectedImplicitObject) {
injectedImplicitObject.doSomethingElse();
}
}
我不喜欢公开父类变量。这有点危险,因为除非您将其设置为最终版本,否则任何子类都可以破坏/替换它。因此,很难保护您的API不受不良使用的影响。您的最佳选择:为什么不将doSomething()放在MyClass中?或者你可以在超类上实现并使用隐式对象的最终getter。这正是我担心的。我不喜欢公开父类变量。这有点危险,因为除非您将其设置为最终版本,否则任何子类都可以破坏/替换它。因此,很难保护您的API不受不良使用的影响。您的最佳选择:为什么不将doSomething()放在MyClass中?或者你可以在超类上实现并使用隐式对象的最终getter。这正是我所担心的。这种机制可以解决覆盖问题,但不能解决可见性问题,我觉得我不得不使用隐式方法(而不是对象)。这意味着该类强制您在逻辑上而不是在物理上使用visible API中未定义的部分。在我看来,这仍然是可以改进的。是的,因为这取决于谁在控制逻辑。有两种方法:您有一个父类,它提供了一组实用方法,而这些方法实际上是在子类上运行的。但是,如果您想要强制执行特定的逻辑,那么就由父级来执行所有逻辑,并调用可重写的方法。抽象/接口在这方面很好。但也许我完全没有抓住要点,一个更具体的例子可能会有所帮助。读你的代码我不知道你想去哪里。你想强迫子类在做某件事时调用特定的父类方法吗?我只是想问,这是否是一个最佳实践解决方案,如果不是,如何以更精细的方式对API建模way@user1902288保护区被认为是不好的做法(与之相关的陷阱很多)。“保护字段”解决方案限制了一些问题:不安全的同步、变量破坏、API演变和向后兼容性问题。。。换句话说,保护字段将为您提供更多的可能性来修复基类的糟糕设计/使用。好吧,这种机制将修复覆盖问题,但不会解决可见性问题,我觉得不知何故我强制使用隐式方法(而不是对象)。这意味着类强制您在逻辑上而不是物理上