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演变和向后兼容性问题。。。换句话说,保护字段将为您提供更多的可能性来修复基类的糟糕设计/使用。好吧,这种机制将修复覆盖问题,但不会解决可见性问题,我觉得不知何故我强制使用隐式方法(而不是对象)。这意味着类强制您在逻辑上而不是物理上