Passing Object of different classes as an argument to same method - java

Let's say I have three Classes A,B,C.
All three do the same thing, but in a different way, they differ in efficiency.
All the method names, variable names inside the three classes are same.
class A{
public static int method(){
......
return result;
}
}
class B{
public static method(){
......
return result;
}
}
class C{
public static method(){
......
return result;
}
}
I have test class, which has a method to test the code in the above three classes. Since this testMethod() is common to all the three classes, is there a way to call this method with objects of classes A,B,C ?
class Test{
public static int testMethod(Object ABC)
{
return ABC.method();
}
public static void main(String[] args){
A a = new A();
SOP(testMethod(a));
B b = new B();
SOP(testMethod(b));
C c = new C();
SOP(testMethod(c));
}
}
The only approach I can think of is creating three different methods for each of the classes, like this.
class Test{
public static int testMethodA(A a)
{
return a.method();
}
public static int testMethodB(B b)
{
return b.method();
}
public static int testMethodC(C c)
{
return c.method();
}
public main()
{
//call to each of the three methods
............
}
What is the best approach to this scenario? Basically I want to have only one method that can test all three classes.

Create an interface with the common method for all classes. Then, make each class implement this interface. In your test code, use the interface as parameter type and pass an instance of each class to the method. Note that when you do this, the method to test should not be static.
In code:
public interface MyInterface {
//automatically public
int method();
}
public class A implements MyInterface {
#Override //important
//not static
public int method() {
/* your implementation goes here*/
return ...;
}
}
public class B implements MyInterface {
#Override //important to check method override at compile time
public int method() {
/* your implementation goes here*/
return ...;
}
}
//define any other class...
Then the test:
public class Test {
//using plain naive console app
public static void main(String[] args) {
MyInterface myInterfaceA = new A();
testMethod(myInterfaceA);
MyInterface myInterfaceB = new B();
testMethod(myInterfaceB);
//and more...
}
public static void testMethod(MyInterface myInterface) {
myInterface.method();
}
}
Or if you prefer to use JUnit:
import static org.hamcrest.Matchers.*;
import static org.junit.Assert.*;
public class MyInterfaceTest {
MyInterface myInterface;
#Test
public void methodUsingAImplementation() {
myInterface = new A();
//code more human-readable and easier to check where the code fails
assertThat(myInterface.method(), equalTo(<expectedValue>));
}
//similar test cases for other implementations
}

Related

How do you pass an instance of a class as an argument for a method of that class?

Let's say I have this code. When using an instance of ClassA, how do I pass the instance of the class to the method methodA?
public class ClassA {
public static int methodA(ClassA class) {
return 1;
}
}
//This is wrong but this is what I'm trying to do
public class Main {
public static void main(String [] args) {
ClassA classa = new ClassA();
classa.methodA(classa);
}
}
The way to achieve this is correct. Just use another name, because class is a reserved keyword for class definition
public static int methodA(ClassA instance) {
return 1;
}
Your approach works but you must not use the keyword class as a variable name. Try
public class ClassA {
public static int methodA(ClassA clazz) {
return 1;
}
}

static inheritance: is it possible? Are there better solutions?

Consider this example (warning-very bad code):
public abstract class A {
static float foo;
public static void loadfoo(float incomingfoo) {
foo = incomingfoo;
}
public static void displayfoo() {
System.out.println("your foo is" +foo);
}
}
Class B extends Class A
public class B extends A {
static float foo;
//#Override (overide is not allowed for static methods. dis is a problem...)
public static void loadfoo(float incomingfoo){
foo = incomingfoo;
}
}
Class C is pretty much the same as B
public class C extends A {
static float foo;
//#Override
public static void loadfoo(float incomingfoo) {
//I would like a different static variable loaded into this class using this method
foo = incomingfoo;
}
}
finally the main Class runs the thing
public class Main {
public static void main(String whatever[]){
B.loadfoo(5);
C.loadfoo(8);
B.displayfoo();
C.displayfoo();
}
}
so the output of this is :
your foo is0.0
your foo is0.0
and I am aware this is because the displayfoo class reference the static foo in Class A, so please disregard this. I assume I have now been specific enough about describing my problem and goal. solutions anyone?
Edit: I feel like an idiot I completely forgot to actually state what I wanted to accomplish, but really all I want is for B and C to have there own static variables loaded into them without altering A's variable, which should be the default.
It looks like you need static access to two stateful objects with the same structure. In this case, an enum might be a solution:
public enum A {
B, C;
private float foo;
// getter and (optional) setter for foo here
public void displayFoo() { System.out.println("This foo is " + foo); }
}
This way you can still access your object statically, but don't need to duplicate anything else:
A.B.setFoo(5);
A.C.setFoo(8);
A.B.displayFoo(); // 5
A.C.displayFoo(); // 8
If you then need a static default, I would make it a method on A:
enum A {
A getDefault() { return A.B; }
}
A.getDefault().displayFoo();
It seems that first you want to load the values using loadfoo to foo and then display the value of that foo using the displayfoo method. Well, I don't think there is anyway to do it using static methods.You can do this by making displayfoo() method abstract and overriding the same in the subclasses B and C.
Here is the code:
abstract class A {
float foo;
public void loadfoo(float incomingfoo){
foo = incomingfoo;
}
public abstract void displayfoo();
}
class B extends A{
#Override
public void loadfoo(float incomingfoo){
foo = incomingfoo;
}
#Override
public void displayfoo(){
System.out.println("foo is " + foo);
}
}
class C extends A{
#Override
public void loadfoo(float incomingfoo){
this.foo = incomingfoo;
}
#Override
public void displayfoo(){
System.out.println("foo is " + foo);
}
}
public class Main {
public static void main(String whatever[]){
B b = new B();
C c = new C();
b.loadfoo(5);
c.loadfoo(5);
b.displayfoo();
c.displayfoo();
}
}
You can also check the same kind of question here.
Static methods should be used by static method access and not by object instance. It's not supposed to be virtual because it's not belong to the object.
If you call B.loadfoo() then a method of B class is called.
If you call C.loadfoo() then a method of C class is called.
You cannot call a static method if it doesn't exist in the class.
There's no point to use static methods if you want to use polimorphism.

How do I use super in java?

public class A {
public void foo() {
System.out.println("A's foo");
}
}
public class B extends A {
public void foo() {
System.out.print("B's foo");
}
}
public class Test1 {
public static void main(String[] args){
A a= new B();
a.foo();
}
}
I want to use A's foo, what is the syntax for doing that? I tried a.super.foo();.
Thank you
You can only do so from within the class B. You won't be able to invoke A's foo from outside A or B classes.
A a= new B(); will always set the reference a to an instance of B. Thus, even though you cast it to A, at runtime the method that gets invoked is B.foo. That's runtime polymorphism.
I am really uneasy about a design that needs to do this kind of thing. If you want the object to behave like an A, why did you create a B?
You cannot use super from the outside of the class. Assuming you really, really need this (but I really doubt you can't find a better way) the best you can do about it is to expose a method that does this call to the outside:
public class B extends A {
public void super_foo() {
super.foo();
}
public void foo() {
System.out.print("B's foo");
}
}
public class Test1 {
public static void main(String[] args){
A a= new B();
a.super_foo();
}
}
Here is it
public class A {
public void foo() {
System.out.println("A's foo");
}
}
public class B extends A {
public void foo() {
super.foo();
System.out.print("B's foo");
}
}
public class Test1 {
public static void main(String[] args){
A a= new B();
a.foo();
}
}
You can't access it. The keyword is that it has been overridden by Java so it's no longer accessible.
What you want to achieve will work if the method is static. Non virtual methods in java
public class A {
public static void foo() {
System.out.println("A's foo");
}
}
public class B extends A {
public static void foo() {
System.out.print("B's foo");
}
}
public class Test1 {
public static void main(String[] args){
A a= new B();
a.foo();
}
}

Can a method in an inner class access a parent class method?

I'm not sure if my question title describes my situation aptly, so my apologies if it doesn't! Anyway, let's say I have the following code snippet (visibility is as stated):
public class ChildClass extends ParentClass {
// more code
private void myMethod() {
MyClass mine = new MyClass() {
public void anotherMethod() {
// insert code to access a method in ParentClass
}
};
}
}
Is it possible for code within anotherMethod() to access a protected method found in ParentClass? If so, how can this be done?
I've tried something like...
(ParentClass.this).parentMethod();
...but obviously it doesn't work due to scope issues.
This compiles fine:
class MyClass {
}
class ParentClass {
protected void parentMethod() {
}
}
class ChildClass extends ParentClass {
private void myMethod() {
MyClass mine = new MyClass() {
public void anotherMethod() {
parentMethod(); // this works
}
};
}
}
A non-static inner class can access all methods of the enclosing class as if it were it's own methods:
public class Test {
public int getOne() {
return 1;
}
public class Inner {
public int getEnclosingOne() {
return getOne(); // this works...
}
}
}
A static inner class can not, as a static inner class is not bound to an instance of the parent class. That can only call static methods on the enclosing class.
As for methods when taking into account inheritance, an method in a non-static inner class can use all the methods of the enclosing (outer) class.
The interesting part is Test2.super.getOne() which indeed obtains getOne() from Test2.super, which is a Test. This is just like Test2 would access the method, namely using super though prefixed with Test2 to indicate you're accessing the namespace of the outer class.
public class Test2 extends Test {
public int getInnerOuterParentOne() {
Inner2 inner2 = new Inner2();
return inner2.getOuterParentOne();
}
public int getInnerOuterOne() {
Inner2 inner2 = new Inner2();
return inner2.getOuterOne();
}
public int getOne() {
return 2;
}
public class Inner2 {
public int getOuterOne() {
return getOne();
}
public int getOuterParentOne() {
return Test2.super.getOne();
}
}
public static void main(String[] args) {
Test2 test2 = new Test2();
System.out.println(test2.getInnerOuterOne()); // 2
System.out.println(test2.getInnerOuterParentOne()); // 1
}
}
There is no way to access "parent class method" in Java, irrelatively to visibility (except for super.parentMethod() in subclass's parentMethod()).
That is, if ChildClass overrides parentMethod(), there is no way to call ParentClass.parentMethod() (bypassing ChildClass.parentMethod()) from other methods of ChildClass.
However, if ChildClass doesn't override parentMethod(), that method is inherited by ChildClass, so that you can access it as a ChildClass's method, i.e. simply as parentMethod().

extends of the class with private constructor

Suppose we have the following code:
class Test {
private Test() {
System.out.println("test");
}
}
public class One extends Test {
One() {
System.out.println("One");
}
public static void main(String args[]) {
new One();
}
}
When we create an object One, that was originally called the parent class constructor Test(). but as Test() was private - we get an error.
How much is a good example and a way out of this situation?
There is no way out. You have to create an available (protected, public or default) super constructor to be able to extend test.
This kind of notation is usually used in utility classes or singletons, where you don't want the user to create himself an instance of your class, either by extending it and instanciating the subclass, or by simply calling a constructor of your class.
When you have a class with only private constructors, you can also change the class to final because it can't be extended at all.
Another solution would be having a method in test which create instances of test and delegate every method call from One to a test instance. This way you don't have to extend test.
class Test {
private Test() {
System.out.println("test");
}
public static Test getInstance(){
return new Test();
}
public void methodA(){
//Some kind of implementation
}
}
public class One {
private final Test test;
One() {
System.out.println("One");
test = Test.getInstance();
}
public void methodA(){
test.methodA();
}
public static void main(String args[]) {
new One();
}
}
Make the constructor of test non-private or move One into test.
BTW, your sample code contains a few issues:
classes should be named title case (Test instead of test)
I'd suggest to make the One's constructor private unless it is called from a different class in the same package
Actually, I found there is a way out. Like this:
class Base {
private Base() {
}
public void fn() {
System.out.println("Base");
}
public static class Child extends Base {
public void fn() {
System.out.println("Child");
}
}
public static Base getChild() {
return new Child();
}
}
Now, you can use getChild() to get instance of the extended class.

Categories

Resources