0

Question

As defined in the pseudo-code below, why does an inherited public method (setContentView) of a parent class (MyCustomClassA) defined in a separate package (packageB) not resolve despite the public methods directly defined in said parent class (myPublicMethod) do resolve?

As both myPublicMethod and setContentView are public methods, I'm quite confused as to why one is able to resolve while the other is not.

Minimal Example Pseudo Code

A summary of the hierarchy is shown in the pseudo-code below as well as comments describing the tooltips and errors shown by Android Studio:

package packageA;

public abstract class BaseClass extends Activity{
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState)
        setContentView(layoutID); // Tooltip shows inheritance from android.app.Activity public void setContentView(@LayoutRes int layoutResID)
    }
}

package packageB;

import packageA.BaseClass

public abstract class MyCustomClassA extends BaseClass{
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState)
        setContentView(layoutID); // Tooltip shows inheritance from android.app.Activity public void setContentView(@LayoutRes int layoutResID)
    }

}

package packageB;

import packageB.MyCustomClassA

public abstract class MyCustomClassB extends MyCustomClassA{
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState)
        setContentView(layoutID); // Tooltip shows inheritance from android.app.Activity public void setContentView(@LayoutRes int layoutResID)
        myPublicMethod(); // Tooltip shows this resolves to packageB.MyCustomClassA
    }
    public void myPublicMethod() {
    }
}

package packageC;

import packageB.MyCustomClassA

public abstract class MyCustomClassC extends MyCustomClassA{
    protected void onCreate(Bundle savedInstanceState){
        super.onCreate(savedInstanceState)
        setContentView(layoutID); // Error: Cannot resolve method 'setContentView' in MyCustomClassC
        myPublicMethod(); // Tooltip shows this resolves to packageB.MyCustomClassA
    }
}

What have I tried so far:

  1. Using Android Studio I Ctrl+click the parent classes and verify that they are all pointing to the correct classes.
  2. I Build -> Clean Project and Invalidate Caches and Restart to ensure nothing in the Cache is outdated.
  3. I created a dummy class MyCustomClassB to test whether the setContentView method would be resolvable within the same package. It does resolve. This led me to think it might be a package/protected or otherwise access issue, but as setContentView is a public method in Activity, I'm stuck for additional troubleshooting ideas.
  4. Read this , this, and this among several others related to inheritance, and everything I read only further confirms that this should be possible.

Is it possible this is gradle related? I've gone through the project and app level gradle files in great detail as well, trying to eliminate any possible duplicate dependencies, or things that might cause aliasing, but apart from that I've hit a wall for ideas. Any other ideas of where to continue looking for an error or can you explain why this fundamentally doesn't work (i.e. this is not an error in the code, but an error in my understanding of inheritance)?

topher217
  • 1,188
  • 12
  • 35

1 Answers1

0

I attempted to build despite the linter errors and received a bit more helpful of an error. This appeared to be the origin of the origin of the build errors, which was thrown at the definition of public abstract class MyCustomClassC extends MyCustomClassA:

error: cannot access BaseClass

So it looks like MyCustomClassC is able to access MyCustomClassA without issue, but not the parent (BaseClass) of MyCustomClassA.

Looking back at my gradle build files, I seem to have found the issue. I previously had only this dependency in the MyCustomClassC app-level gradle build file:

dependencies {
    implementation(project(":packageBModule"))
}

while the dependencies for packageB where in their own build file.

dependencies {
    implementation(project(":packageAModule"))
}

but after adding the dependencies of both to my packageCModule build file, i.e.:

dependencies {
    implementation(project(":packageBModule"))
    implementation(project(":packageAModule"))
}

everything resolves. I was under the impression that I did not have to specify dependencies of all parent classes within each subclass module, and they would be brought in via the inheritance, but this appears to be an incorrect assumption. Looks like I need to finally bite the bullet and start reading through the gradle docs in further detail as I'd guess there is a more optimal way to manage dependencies for inherited classes rather than just copying and pasting them in an ever growing list for an ever deeper inheriting subclass.

topher217
  • 1,188
  • 12
  • 35