I have an abstract Java class MyAbstractClass with a private method. There is a concrete implementation MyConcreteClass.
public class MyAbstractClass {
private void somePrivateMethod();
}
public class MyConcreteClass extends MyAbstractClass {
// implementation details
}
In my groovy test class I have
class MyAbstractClassTest {
void myTestMethod() {
MyAbstractClass mac = new MyConcreteClass()
mac.somePrivateMethod()
}
}
I get an error that there is no such method signature for somePrivateMethod. I know groovy can call private methods but I'm guessing the problem is that the private method is in the super class, not MyConcreteClass. Is there a way to invoke a private method in the super class like this (other than using something like PrivateAccessor)?
thanks
Jeff
The fact that you can call private methods is a bug in the Groovy language, not a feature. However, I believe this bug was introduced deliberately as a form of compromise when making some changes to the way closures behave.
Even though you can call private methods, you should not, because hopefully one day this bug will be fixed, and if your program relies on calling private methods it will be broken.
If you really insist on (ab)using this undocumented behaviour, you could try using something like ReflectionUtils to call private methods in parent classes.
Another workaround is to provide a method in the concrete class that calls the private method in the parent class. For example, the following code "works", but it still relies on accessing private members, which is bad
class Parent {
private foo() {println "foo"}
}
class Child extends Parent {
public bar() {super.foo()}
}
new Child().bar()
Related
I'm testing out an android app, and am using a library provided to me by my university, classes 1-4 come from my lecturer for our use.
I have a class structured like so:
ClassOne
public ClassOne {
private ClassTwo clsTwo;
...
public ClassOne(ClassTwo p1)
public ClassTwo getClsTwo();
}
ClassTwo is structured as so:
public ClassTwo {
private ClassThree clsThree;
...
public ClassTwo()
public ClassThree getClsThree();
}
ClassThree is structured as so:
public ClassThree {
private HashMap<Bitmap> mBitmaps;
...
private ClassFour clsFour;
...
public ClassThree(ClassFour p1);
...
public loadFile(String path, String name);
public loadFileFromAssetStore(String name);
}
ClassFour is structured as so:
public ClassFour {
...
public ClassFour(Context context);
...
}
The Class I am testing is ClassFive, which specifically has the methods highlighted which are causing issues:
public ClassFive {
private Bitmap myBitmap
...
public ClassFive(...,...,...,ClassOne p,...){
super(..., p,
p.getClsTwo().getClsThree().loadFileFromAssetStore("Default value"));
this.myBitmap = loadCorrectFile(...,p);
}
private Bitmap loadCorrectFile(..., ClassOne p){
String strCorrectFileName;
switch(...){
...
// set value of strCorrectFileName
...
}
this.myBitmap = p.getClsTwo().getClsThree().loadFileFromAssetStore(strCorrectFileName);
}
}
My problem is I need to test methods using constructor of ClassFive, however the tests are all 'falling over' when invoking the constructor with a NPE.
public class ClassFiveTest {
#Mock
private ClassOne mockClassOne = Mockito.Mock(ClassOne.class);
#Test
public void testConstructorGetName() throws Exception {
ClassFive instance = new ClassFive(..., mockClassOne);
...
// Assertions here
...
}
My problem is that a null pointer exception is being returned before my test can get to my assertions. Do I need to be using mockito? Because I tried that - maybe I'm just using it wrong for this instance. Or do I need to be using instrumented tests? When I tried instrumented testing I found it impossible to get access to ClassOne and ClassTwo?
This is easily remedied with some stubbing.
#Mock private ClassOne mockClassOne; // Don't call `mock`; let #Mock handle it.
#Mock private ClassTwo mockClassTwo;
#Mock private ClassThree mockClassThree;
#Override public void setUp() {
MockitoAnnotations.initMocks(this); // Inits fields having #Mock, #Spy, and #Captor.
when(mockClassOne.getClsTwo()).thenReturn(mockClassTwo);
when(mockClassTwo.getClsThree()).thenReturn(mockClassThree);
// Now that you can get to mockClassThree, you can stub that too.
when(mockClassThree.loadFileFromAssetStore("Default value")).thenReturn(...);
when(mockClassThree.loadFileFromAssetStore("Your expected filename")).thenReturn(...);
}
In summary, Mockito is designed for easily making replacement instances of classes so you can check your interactions with your class-under-test: Here, you're creating fake ("test double") implementations of ClassOne, ClassTwo, and ClassThree, for the purpose of testing ClassFive. (You might also choose to use real implementations or manually-written fake implementations, if either of those make more sense for your specific case than Mockito-produced implementations.) Unless you otherwise stub them, Mockito implementations return dummy values like zero or null for all implemented methods, so trying to call getClsThree on the null returned by getClsTwo causes an NPE until you stub getClsTwo otherwise.
If the stubs for mockThree change between tests, you can move them into your test before you initialize your ClassFive. I'm also sticking to JUnit3 syntax and explicit initMocks above, because Android instrumentation tests are stuck on JUnit3 syntax if you're not using the Android Testing Support Library; for tests on JUnit4 or with that library you can use a cleaner alternative to initMocks. Once you get comfortable with Mockito, you can also consider RETURNS_DEEP_STUBS, but I like to keep my stubs explicit myself; that documentation also rightly warns "every time a mock returns a mock, a fairy dies".
Isn't this long and complicated, and doesn't it feel unnecessary? Yes. You are working around violations of the Law of Demeter, which Wikipedia summarizes (emphasis mine) as:
Each unit should have only limited knowledge about other units: only units "closely" related to the current unit.
Each unit should only talk to its friends; don't talk to strangers.
Only talk to your immediate friends.
Your problem and your verbose solution both stem from ClassFive depending on ClassThree, but only via ClassOne and ClassTwo implementation details. This isn't a strict law, but in your own code outside of university you might treat this as a sign to revisit the designs of ClassOne, ClassTwo, and ClassFive and how they interact. If ClassFive were to depend directly on ClassThree, it may be easier to work with the code in production and tests, and maybe you'd find that ClassOne isn't necessary at all.
// ClassFive doesn't just work with its dependency ClassOne, it works directly with its
// dependency's dependency's dependency ClassThree.
super(..., p,
p.getClsTwo().getClsThree().loadFileFromAssetStore("Default value"));
I'd like to support the answer of#JeffBowman by showing how the code could look like.
The proposed solution implies that you add another parameter to the constructors parameter list with is far to long already. Your code could be simplified by following the Favor composition over inheritance principle
Most parameters of the constructor in ClassFive are only there to be pass to the parent classes constructor.
In this situation it would be better not to inherit from that super class, but create an interface (e.g.: extract with support of your IDE) of the super class (lets call is SuperInterface that is implemented by both, the super class and CLassFive.
The you replace all the parameters that are passed to the super class by one single parameter of type SuperInterface.
Then you simply delegate all methods of SuperInterface that are not implemented by CLassFive directly to the SuperInterface instance.
This is what it would look like:
public interface SuperInterface {
// all public methods of the super class.
}
public class ClassFive implements SuperInterface{
private final SuperInterface superClass;
private final Bitmap myBitmap
public ClassFive(SuperInterface superClass ,ClassTree p){
this.superClass = superClass;
p.loadFileFromAssetStore("Default value"));
this.myBitmap = loadCorrectFile(...,p);
}
#Override
public void someMethodDeclaredInInterface(){
this.superClass.someMethodDeclaredInInterface();
}
}
This pattern also works vice versa if you don't like the duplicated method delegations all over your classes extending SuperInterface.
This alternative approach is useful if your specializations override just a few methods of the interface and almost all the same.
In that case the interface you create may not be implemented by the super class. The methods declared in the interface don't even need to be part of the super classes public methods. The interface only declares methods that the super class (should now better be called "generic class") needs to use the derived behavior.
This would look like this:
interface AnimalSound{
String get();
}
class DogSound implements AnimalSound{
#Override
public String get(){
return "wouff";
}
}
class CatSound implements AnimalSound{
#Override
public String get(){
return "meaw";
}
}
class Animal {
private final AnimalSound sound;
public Animal(AnimalSound sound){
this.sound = sound;
}
public String giveSound(){
return sound.get();
}
}
And this is how we use it:
List<Animal> animals = new ArrayList<>();
animals.add(new Animal(new DogSound()));
animals.add(new Animal(new CatSound()));
for(Animal animal : animals){
System.out.println(animal.giveSound());
}
In the context of android.accounts.AccountManager:
public class AccountManager {
private abstract class AmsTask extends FutureTask<Bundle> implements AccountManagerFuture<Bundle> {
...
}
}
I would like to find the inner class by name using reflection, as I require a Class object to determine staticness of member methods. In the simple case
public class AccountManager {
public class Foo {
...
}
}
This can be done using Class.forName("android.accounts.AccountManager$Foo"). However, the private modifier eliminates this possibility. I tried searching through Class.forName("android.accounts.AccountManager").getDeclaredClasses(), but it returns an empty list. Its specification covers private member classes, so I am at a loss why it is not returned by the getter. I presume it has something to do with abstract.
EDIT: Experiments have shown getDeclaredClasses() to work with the following snippet, but not with the actual Android class.
public class Test {
private abstract class AmsTask extends LinkedList implements TestInterface {
...
}
private interface TestInterface{}
}
The suggestion that using AccountManager's class loader might help, did not turn out to be fruitful.
Class am = Class.forName("android.accounts.AccountManager");
Class.forName("android.accounts.AccountManager$AmsTask",false,am);
resulted in a ClassNotFoundException during the latter call.
I have an abstract class inherited by two concrete classes.
public abstract class AbstractClass {
public abstract void operation1();
}
public class ConcreteClassA extends AbstractClass {
#Override
public void operation1() {
// Do work
}
public void operation2() {
// Do some other work
}
}
public class ConcreteClassB extends AbstractClass {
#Override
public void operation1() {
// Do work
}
}
Now, to take advantage of dynamic binding I create two objects while programming to the interface.
private AbstractClass classA = new ConcreteClassA();
private AbstractClass classB = new ConcreteClassB();
But this does not allow me to call method operation2() on classA. I can fix this by using a downcast.
((ConcreteClassA) classA).operation2();
But downcasts are considered ugly in OOP especially when you have to use them a lot. Alternatively, I can give up programming to the interface.
private ConcreteClassA classA = new ConcreteClassA();
But then I lose the dynamic binding. Another option is to move operation2() to the AbstractClass so that I can restore the dynamic binding.
public abstract class AbstractClass {
public abstract void operation1();
public abstract void operation2();
}
But then ConcreteClassB needs to override operation2() leaving the implementation empty since this class does not need this method.
Lastly, I could move operation2() to the AbstractClass and provide a default implementation which may be overridden or not.
public abstract class AbstractClass {
public abstract void operation1();
public void operation2() {
// Some default implementation
}
}
But this gives classB access to operation2() which I would rather avoid.
There does not seem to be a clean solution to call subclass specific methods while maintaining dynamic binding at the same time. Or is there?
There are at least a few ways to deal with this circumstance and, really, the right one depends on your particular requirements.
Ask yourself, "are both operation1 and operation2 part of the contract specified by my type?"
If the answer is clearly no, then you should not pollute the contract of your type by adding collateral methods to it. You should next ask yourself, "why am I not using interfaces to specify separate types, eg.: instead of AbstractClass, why am I not using MyInterface1 and MyInterface2 (each with its own separate contract)? Interfaces provide a limited form of multiple inheritance, and your implementing classes can implement any and all interfaces that pertain to it. This is a strategy commonly used by the Java Platform Libraries. In this circumstance, explicit casting to the type whose contract you want to use is exactly the right thing to do.
If the answer is clearly yes, then you should have both methods in your type ... but you should still ask yourself, "why am I not specifying my type with an interface"? In general, you should specify types with interfaces rather than abstract classes, but there are reasons to use the latter.
If the answer is somewhere in between, then you can consider specifying optional methods in your type. These are methods which are included in the contract of your type, but which implementing classes are not required to implement. Before Java 8, each implementing type would need to throw a UnsupportedOperationException for any optional methods that it did not implement. In Java 8, you can do something like this for optional methods:
======
public interface MyType {
void contractOperation1();
default void optionalOperation2() {
throw new UnsupportedOperationException();
}
}
A class that implements this interface will need to provide an implementation for contractOperation1(). However, the class will not need to provide an implementation for optionalOperation2() and if this method is invoked on an implementing class that has provided no implementation of its own, then the exception is thrown by default.
abstract class don't have the object,we just create the reference of that class and use it.
like:
instead of this-
private AbstractClass classA = new ConcreteClassA();
private AbstractClass classB = new ConcreteClassB();
use this one
private AbstractClass classA;
private AbstractClass classB;
If we will create an object of the abstract class and calls the method having no body(as the method is pure virtual) it will give an error. That is why we cant create object of abstract class. Here is a similar StackOverflow question. In short, it is legal to have a public constructor on an abstract class.
more details are here:about abstraction instance
I have an interface called Relation, implemented by a class BasicRelation, and extended by subclasses (e.g. ParentChild, Sibling, Spouse). While developing my code, I realized that I often need a method which takes a String representation of a relation to create it. For example:
public class ParentChild implements Relation extends BasicRelation {
// e.g. "Jack is Emily's father. Jill is her mother." will return the list
// <ParentChild(Jack, Emily), ParentChild(Jill, Emily)>
static List<ParentChild> fromSentence(String s) {
...
}
}
Now, since I find myself needing this method (fromSentence(String)) in every class, except perhaps in BasicRelation, I would like to move it up the hierarchy. The problem is that the internal details of the method is subclass-dependent, so I can't have it as a static method in the interface Relation or the superclass BasicRelation.
Unfortunately, in Java, it is also not possible to have a static abstract method.
Is there any way to ensure that every subclass of BasicRelation (or every class implementing Relation) implements fromSentence(String)? If no, should I be designing this in a completely different way? I guess this last question is more of a request for design-advice than a question.
Why does the static method need to be in the interface? What's stopping you from having a 'Utility' class and having the method in there?
public class RelationUtility {
public static BasicRelation relationFactory(String asString) {
....
}
}
As a static method, there is no reason other than access to private members, which can also be accomplished by by 'default' permissions on those members....
You can try making the BasicRelation class an abstract class and use an abstract fromSentence(..) method. This would require the ParentChild class to override and implement the fromSentence method because you can't create an object for ParentChild without implementing fromSentence()
public abstract class BasicRelation extends Relation(){
public abstract List<..> fromSentence(String s);
}
public class ParentChild implements Relation extends BasicRelation {
fromSentence(){
//parentChild class's implementation
}
}
If I understood right... you can try an approach like this
public class BasicRelation {
public abstract List<ParentChild> fromSentenceInSubclass(s);
public List<ParentChild> fromSentence(String s){
fromSentenceInSubclass(s);
}
}
And then you could have:
public class SubclassRelation extends BasicRelation {
public List<ParentChild> fromSentenceInSubclass(s){
// do subclass relation stuff
}
}
You will probably need to change the code a bit and add some Generics around to make it happen the way you want.
Sotirios Delimanolis Factory suggestion might also be an option.
You can have the abstract class BasicRelation include the static method which throws an Exception. That way you will be forced to override (shadow) the static method in the subclasses when you use it.
Something like:
public abstract class BasicRelation {
public static List<..> fromSentence(String s) {
throw new RuntimeException();
}
}
I know that an interface must be public. However, I don't want that.
I want my implemented methods to only be accessible from their own package, so I want my implemented methods to be protected.
The problem is I can't make the interface or the implemented methods protected.
What is a work around? Is there a design pattern that pertains to this problem?
From the Java guide, an abstract class wouldn't do the job either.
read this.
"The public access specifier indicates that the interface can be used by any class in any package. If you do not specify that the interface is public, your interface will be accessible only to classes defined in the same package as the interface."
Is that what you want?
You class can use package protection and still implement an interface:
class Foo implements Runnable
{
public void run()
{
}
}
If you want some methods to be protected / package and others not, it sounds like your classes have more than one responsibility, and should be split into multiple.
Edit after reading comments to this and other responses:
If your are somehow thinking that the visibility of a method affects the ability to invoke that method, think again. Without going to extremes, you cannot prevent someone from using reflection to identify your class' methods and invoke them. However, this is a non-issue: unless someone is trying to crack your code, they're not going to invoke random methods.
Instead, think of private / protected methods as defining a contract for subclasses, and use interfaces to define the contract with the outside world.
Oh, and to the person who decided my example should use K&R bracing: if it's specified in the Terms of Service, sure. Otherwise, can't you find anything better to do with your time?
When I have butted up against this I use a package accessible inner or nested class to implement the interface, pushing the implemented method out of the public class.
Usually it's because I have a class with a specific public API which must implement something else to get it's job done (quite often because the something else was a callback disguised as an interface <grin>) - this happens a lot with things like Comparable. I don't want the public API polluted with the (forced public) interface implementation.
Hope this helps.
Also, if you truly want the methods accessed only by the package, you don't want the protected scope specifier, you want the default (omitted) scope specifier. Using protected will, of course, allow subclasses to see the methods.
BTW, I think that the reason interface methods are inferred to be public is because it is very much the exception to have an interface which is only implemented by classes in the same package; they are very much most often invoked by something in another package, which means they need to be public.
This question is based on a wrong statement:
I know that an interface must be public
Not really, you can have interfaces with default access modifier.
The problem is I can't make the interface or the implemented methods protected
Here it is:
C:\oreyes\cosas\java\interfaces>type a\*.java
a\Inter.java
package a;
interface Inter {
public void face();
}
a\Face.java
package a;
class Face implements Inter {
public void face() {
System.out.println( "face" );
}
}
C:\oreyes\cosas\java\interfaces>type b\*.java
b\Test.java
package b;
import a.Inter;
import a.Face;
public class Test {
public static void main( String [] args ) {
Inter inter = new Face();
inter.face();
}
}
C:\oreyes\cosas\java\interfaces>javac -d . a\*.java b\Test.java
b\Test.java:2: a.Inter is not public in a; cannot be accessed from outside package
import a.Inter;
^
b\Test.java:3: a.Face is not public in a; cannot be accessed from outside package
import a.Face;
^
b\Test.java:7: cannot find symbol
symbol : class Inter
location: class b.Test
Inter inter = new Face();
^
b\Test.java:7: cannot find symbol
symbol : class Face
location: class b.Test
Inter inter = new Face();
^
4 errors
C:\oreyes\cosas\java\interfaces>
Hence, achieving what you wanted, prevent interface and class usage outside of the package.
Here's how it could be done using abstract classes.
The only inconvenient is that it makes you "subclass".
As per the java guide, you should follow that advice "most" of the times, but I think in this situation it will be ok.
public abstract class Ab {
protected abstract void method();
abstract void otherMethod();
public static void main( String [] args ) {
Ab a = new AbImpl();
a.method();
a.otherMethod();
}
}
class AbImpl extends Ab {
protected void method(){
System.out.println( "method invoked from: " + this.getClass().getName() );
}
void otherMethod(){
System.out.println("This time \"default\" access from: " + this.getClass().getName() );
}
}
Here's another solution, inspired by the C++ Pimpl idiom.
If you want to implement an interface, but don't want that implementation to be public, you can create a composed object of an anonymous inner class that implements the interface.
Here's an example. Let's say you have this interface:
public interface Iface {
public void doSomething();
}
You create an object of the Iface type, and put your implementation in there:
public class IfaceUser {
private int someValue;
// Here's our implementor
private Iface impl = new Iface() {
public void doSomething() {
someValue++;
}
};
}
Whenever you need to invoke doSomething(), you invoke it on your composed impl object.
I just came across this trying to build a protected method with the intention of it only being used in a test case. I wanted to delete test data that I had stuffed into a DB table. In any case I was inspired by #Karl Giesing's post. Unfortunately it did not work. I did figure a way to make it work using a protected inner class.
The interface:
package foo;
interface SomeProtectedFoo {
int doSomeFoo();
}
Then the inner class defined as protected in public class:
package foo;
public class MyFoo implements SomePublicFoo {
// public stuff
protected class ProtectedFoo implements SomeProtectedFoo {
public int doSomeFoo() { ... }
}
protected ProtectedFoo pFoo;
protected ProtectedFoo gimmeFoo() {
return new ProtectedFoo();
}
}
You can then access the protected method only from other classes in the same package, as my test code was as show:
package foo;
public class FooTest {
MyFoo myFoo = new MyFoo();
void doProtectedFoo() {
myFoo.pFoo = myFoo.gimmeFoo();
myFoo.pFoo.doSomeFoo();
}
}
A little late for the original poster, but hey, I just found it. :D
You can go with encapsulation instead of inheritance.
That is, create your class (which won't inherit anything) and in it, have an instance of the object you want to extend.
Then you can expose only what you want.
The obvious disadvantage of this is that you must explicitly pass-through methods for everything you want exposed. And it won't be a subclass...
I would just create an abstract class. There is no harm in it.
With an interface you want to define methods that can be exposed by a variety of implementing classes.
Having an interface with protected methods just wouldn't serve that purpose.
I am guessing your problem can be solved by redesigning your class hierarchy.
One way to get around this is (depending on the situation) to just make an anonymous inner class that implements the interface that has protected or private scope. For example:
public class Foo {
interface Callback {
void hiddenMethod();
}
public Foo(Callback callback) {
}
}
Then in the user of Foo:
public class Bar {
private Foo.Callback callback = new Foo.Callback() {
#Override public void hiddenMethod() { ... }
};
private Foo foo = new Foo(callback);
}
This saves you from having the following:
public class Bar implements Foo.Callback {
private Foo foo = new Foo(this);
// uh-oh! the method is public!
#Override public void hiddenMethod() { ... }
}
I think u can use it now with Java 9 release. From the openJdk notes for Java 9,
Support for private methods in interfaces was briefly in consideration
for inclusion in Java SE 8 as part of the effort to add support for
Lambda Expressions, but was withdrawn to enable better focus on higher
priority tasks for Java SE 8. It is now proposed that support for
private interface methods be undertaken thereby enabling non abstract
methods of an interface to share code between them.
refer https://bugs.openjdk.java.net/browse/JDK-8071453