At the moment I have an abstract class which implements an interface. All implementations extend the abstract class to make there own implementation of the interface methods.
The abstract class holds methods which are the same for each implementation f.e. an execute method. I don't want to include the same 'execute' test for each implementation class.
I can successfully test the execute method in the abstract class by creating a test class for one of the implementation classes. The problem is that there will be more classes extending this abstract class and I don't want to write the same execute test in each of those classes.
I would like to somehow test the execute method from the abstract class only once in a specific test class so I can test only the implementation logic of all the other classes.
You can create a test class for your abstract class, too. Although you can't instantiate the abstract class directly, you can still create a concrete implementation class within your test file, just for testing the abstract class, implementing the required methods. You can get an instance for testing e.g. using an anonymous class:
AbstractClassType x = new AbstractClassType() {
#Override
public void doSomething() {
// ...
}
};
public interface BlaInterface {
public String getData();
}
public abstract class AbstractBla implements BlaInterface {
// methot to test only once and not for each class extending this
public void execute() {
// do some stuff which is the same for each extending class
getData();
}
}
public class BlaBla extends AbstractBla {
public String getData() {
return "Blabla";
}
}
So F.E. the above classes I can test the execute() method by testing the BlaBla class. But there will be more classes extending the abstract class and I find it ugly to put the execute() test just random in one of those classes.
So I would like an abstract test for the execute and other test classes just for testing getData f.e.
You can also create a parameterized test class, which takes the instances with the expected result as input and performs the tests.
(However, if you have much verification logic that strongly differs between the different instances, the approach by #vlumi to create an abstract test class might work better, because you can move the verification logic into abstract methods.)
public class MyParameterizedTests {
#ParameterizedTest
#MethodSource("getTestData")
public void test(TestData data) {
assertEquals(data.expectedResult, data.instance.compute());
}
public static TestData[] getTestData() {
return new TestData[] { new TestData(new X(), "x"), new TestData(new Y(), "y") };
}
}
class TestData {
public MyInterface instance;
public String expectedResult;
public TestData(MyInterface instance, String expectedResult) {
this.instance = instance;
this.expectedResult = expectedResult;
}
}
interface MyInterface {
String compute();
}
class X implements MyInterface {
#Override
public String compute() {
return "x";
}
}
class Y implements MyInterface {
#Override
public String compute() {
return "y";
}
}
Related
Here's My code:
public interface Baseinterface {}
abstract class Interface1 implements Baseinterface{}
abstract class Interface2 implements Baseinterface{}
public interface Classinterface {}
And i want to use this code:
public class Myclass(Baseinterface interfaceversion) implements Classinterface{}
Where the kind of interface implementation is passed as a constructor.
So when a function is defined in both of those abstract classes my actual class knows which one to use. I am fairly new at java.
Thanks.
I may be misunderstanding the nature of the question, but here goes:
Given this code which describes two abstract classes that implement the same method as defined by an interface:
interface BaseInterface {
void foo();
}
abstract class ITestA implements BaseInterface {
public void foo() {
System.out.print("A");
}
}
abstract class ITestB implements BaseInterface {
public void foo() {
System.out.print("B");
}
}
public class MyClass {
private BaseInterface enclosed;
MyClass(BaseInterface base) {
enclosed = base;
}
public void foo() {
enclosed.foo(); // call the implementation specific to the instance passed in by constructor
}
}
This could be called like:
public class Test {
void bar() {
// This may look weird cause we're defining an anonymous implementation of the abstract class, without adding any new implementation details
ITestA impl = new ITestA() {};
MyClass myClass = new MyClass(impl);
myClass.foo(); // prints "A"
}
}
I'm learning abstract classes vs interfaces at the moment and trying to figure out situations where to use one over the other. I'm having trouble figuring out this example at the moment:
public interface Face {
public void test();
}
public abstract class Tract {
public void test() {
System.out.println("over here");
}
}
public class Thing extends Tract implements Face {
public void test() {
// what should print out?
}
}
Here, the test() function is implemented in the abstract class. If you don't implement it in the subclass, would it call the abstract class' method and print out "over here"? Does the interface accept implementations from an ancestor class or do you have to implement it in the subclass, therefore overriding the abstract class implementation?
All the interface cares about is that the class has implemented a method called test() that returns void. It does not matter whether the method is implemented in the class directly or in any ancestor (parent) class.
In your case, the Thing class has inherited its definition of test() from Tract, and therefore implements the Face interface without you having to provide a definition explicitly.
In the class "Tract" you have given an implementation for the method coming from the interface. Also you override it in "Thing" class so when calling this method on a Thing instance then this version(Thing version) is going to be called.
All java methods are virtual.
lets consider little bit modified code,
I hope, you will get the idea:
public interface Face {
public void test();
}
public abstract class Tract {
public void test() {
System.out.println("Tract here");
}
}
public class Thing extends Tract implements Face {
public void test() {
System.out.println("Thing here");
}
}
public class Thing2 extends Tract implements Face {
}
lets go to output:
Tract tr = new Tract();
tr.test();
will not compile because you can't instantiate abstract class.
Thing th = new Thing();
th.test();
will print "Thing here"
Thing2 th2 = new Thing2();
th2.test();
will print "Tract here",
because you not overwritten the test() method in abstract class.
Main idea of this approach - you can abstract implementation in the future use
class C {
void print(Face face) {
face.test();
}
}
new C(new Thing()).print();
will print "Thing here";
new C(new Thing2()).print();
will print "Tract here";
You can hide different implementations
But this is not main idea of abstract classes.
main idea abstract classes are:
public interface Face {
public void test();
}
public abstract class Abstract {
abstract public void test();
}
public class Thing1 extends Abstract implements Face {
public void test() {
System.out.println("Thing1 here");
}
}
public class Thing2 extends Abstract implements Face {
public void test() {
System.out.println("Thing2 here");
}
}
main idea - you can declare method without implementation
new C(new Thing1()).print();
will print "Thing1 here";
new C(new Thing2()).print();
will print "Thing2 here";
main idea - you declare the method in abstract class, that you MUST override to compile code.
I hope, this is enough explained answer.
I have the following scenario:
#Component
#Scope("prototype")
public abstract class AbstractA {
protected abstract String getData();
}
Now I will require to create instances of this class in a dynamic manner (using anonymous inner classes). Such as:
#Component
public class B {
public void some_method() {
//Obviously this is wrong, I want to be able to do this through Spring/beans.
new AbstractA() {
protected abstract String getData() {
return "abc";
}
}
}
}
How would I be able to get instrances of the prototype bean in such scenario?
what is the difference between creating an Object of interface and implementing an interface
example :
public interface A{
public void testMethod();
}
on way is creating an object of interface
public class B{
A a = new A(){
#override
public void testMethod(){ //implemtation here }
};
}
other way is
public class B implements A
{
#override
public void testMethod(){}
}
You are wrong:
here you anonymously implement interface and you alrady have instance of annonymouse class
public class B{
A a = new A(){
#override
public void testMethod(){ //implemtation here }
};
}
Here you create named implementation, you only create class without instantiate it.
public class B implements A
{
#override
public void testMethod(){}
}
You can't create an object of interface. Interface it's an abstract class but with all the methods are abstract. In the first code you are creating an anonymous class (i recommend you to read about this feature in java) that implements the interface A, in this case you are limited with the interface's methods even if you define additional method in your implementation you can't call it. In the second code you are creating a class that implements the interface A which means that you have a class that at least contain all the methods defined in the interface A and you can add inside your class B other methods and call its.
I have these 2 classes
class A {
public void foo1() {
...;
foo2();
...;
}
protected abstract foo2();
}
class B extends A {
public foo2() {
......
}
I need foo2 to be static so I can do B.foo2() but I also want the functionality in class A to remain.n
Any suggestions?
}
You can't override static methods or implement abstract methods as static.
Static methods are defined on a class definition, not on a class instance. Abstract methods are defined on a class instance.
What you said doesn't make sense in fact.
Although I don't quite get why you need to do it, there is a workaround:
class B {
#Override
public void foo() {
fooUtil();
}
public static void fooUtil() {
// your impl here
}
}
Then you can do B.fooUtil() instead, and using its behavior to override A.foo().