Replace empty method with method from a class where it is used - java

In the following scenario, I want to replace Class B's (similarly D, E, F, etc.) method doSomething() with the method in Class A where it will be used. How would I go about this? Made up some example, hope it gets the message across
public class B implements GetNames{
public void getNameA(){ return "NameA"; }
public void getNameB() { return "NameB"; }
public void doStuff(){
//print names
doSomething(getNameA(), getNameB());
//print names
}
public void doSomething(String a, String b){}
}
public class A{
public void someMethod(){
B b = new B();
b.doStuff(); //*So I want it to call the method in B but somehow replace the doSomething method in B with the doSomething method in A
}
public void doSomething(String a, String b){
//print 'blabla' + a
//print 'blablabla' + b
//concatenate and print
}
}

Made abstract class A implement interface GetNames and then extend it in class B:
public abstract class A implements GetNames {
public void doSomething(String a, String b){
//print 'blabla' + a
//print 'blablabla' + b
//concatenate and print
}
}
public class B extends A {
public void getNameA(){ return "NameA"; }
public void getNameB() { return "NameB"; }
public void doStuff(){
// class A's doSomething will be called
doSomething(getNameA(), getNameB());
//print names
}
}

Class A should extend class B. If you make B an abstract class, the B.java file would look something like this:
public abstract class B {
...
public abstract void doSomething(String a, String b);
...
}
An abstract class has some functionality, like the getNameA method, which is already defined, but other methods like doSomething are left to its subclasses to implement.
Change class A to read:
public class A extends B {
...
#Override
public void doSomething(String a, String b) {
// custom behaviour
}
}
If what you want is to just make an instance of class B that has a different implementation of the method doSomething then what you could do is this:
B myBInstance = new B() {
#Override
public void doSomething(String a, String b) {
// custom behaviour here
}
};
myBInstance.doStuff();
Style-wise and design-wise though, this is only a quick-and-dirty way to define behaviour for a one-time use of B.

Related

Java: Calling in main implemented Interface Methods from a jUnit - Test

I have the following function:
public static String s(B b) {
int t = b.t();
String r ="Hello ";
for(String z:s) {
boolean x=b.f(t,5);
if(x) {
r+=z;
}
}
return r;
}
Which takes in B - Interface
The Interface B - Methods int t() and boolean f(int a, int b) were implemented in the same class within main as the following:
public static void main(String[] args) {
A.s(new B() { //A - Class
#Override //B - Interface
public int t() {
return 15;
}
#Override
public boolean f(int a, int b) {
return true;
}
});
}
Issue: How can i test the public static String s(B b) - function from a jUnit - test when the function asks for a interface as a parameter, when the interface methods were implemented in main?
The Class is called A, Interface: B
When you want to test your s() method you can provide any reference to an object which implements the B interface. You can define an anonymous class which implements the interface as you did in your main() method. Or you can define a "normal" class which implements the interface as well. So you can write something like this:
public class Whatever implements B
{
/* your methods from B */
}
Then you use this class like any other class inside your unit test:
#Test
public void checkSomething() {
String result = A.s(new Whatever());
Assertions.assertEquals("my string", result);
}

Call method using type variable generics

I have a scenario that i want to create one support class called D which contains a generic method. I have set the upper bound for type variable.
class A{
void show(){
System.out.println("Hello A");
}
}
class B extends A{
void msg(){
System.out.println("Hello B");
}
}
class C extends A{
void msg(){
System.out.println("Hello C");
}
}
class D{
<T extends A> void display(T ob){
ob.msg(); //here i want to do some tricks
}
}
First i want to share my objective. Here msg() function of B and C class has different implementations. I want to create one support class called D that has one display method, using display method i want to call either msg() function of B or C class dependent on instantiation. Can you tell me how can i achieve it?
You need to have the method msg() in class A, otherwise the display() method in class D does not know if this method exist or not in the object that you're passing to it. (What if someone makes a class E that extends A but does not have a msg() method, and you pass an E to D.display()?).
If you don't want to implement the msg() method in class A, then you can make it abstract (and you'll also have to make the class abstract).
abstract class A {
public abstract void msg();
// ...
}
more like an architecture style, I would use an interface for that, so your generic method constrains to <T extends If> void display(T ob) where If is the interface with the abstract method msg
interface If {
void msg();
}
class A {
void show() {
System.out.println("Hello A");
}
}
class B extends A implements If {
#Override
public void msg() {
System.out.println("Hello B");
}
}
class C extends A implements If {
#Override
public void msg() {
System.out.println("Hello C");
}
}
class D {
<T extends If> void display(T ob) {
ob.msg(); // here i want to do some tricks
}
}
You don't need generics for this, there is basic concept called dynamic binding in Java.
abstract class A{
void show(){
System.out.println("Hello A");
}
abstract void msg();
}
class B extends A{
#Override
void msg(){
System.out.println("Hello B");
}
}
class C extends A{
#Override
void msg(){
System.out.println("Hello C");
}
}
class D{
void display(A ob){
ob.msg();
}
}
Here an appropriate instance provided to method will determine which class method should in called at runtime.

Force the execution of a method in a class

I'm using Java and I want to call the method f2 in class A from the class B. Is it possible to do this?
public class A{
private B b = new B();
public void f1(){
b.f3();
}
public void f2(){
// do something;
}
}
public class B{
public void f3(){
// Call f2 of class A from here.
}
}
You need an instance of A in class B and invoke f2 on that instance. For example, you could instantiate one inside the body of f3:
public class B {
public void f3() {
A a = new A();
a.f2();
}
}
Another way would be for f3 to receive an instance of A:
public class B {
public void f3(A a) {
a.f2();
}
}
And yet another way, you could have B instantiate one:
public class B {
private final A a;
public B() { this.a = new A(); }
public void f3() {
this.a.f2();
}
}
And lastly, B could receive one in it's constructor:
public class B {
private final A a;
public B(A a) { this.a = a; }
public void f3() {
this.a.f2();
}
}
The point being that if you want to invoke an instance method on a class you must have an instance of that class in your hand.
Finally, I notice that you have A.f1 invoking B.f3 and from there you want to invoke A.f2. So, it looks like your best option here is the second option above. That is:
public class A {
private final B = new B();
public void f1() { this.b.f3(this); }
public void f2() { /* do something */ }
}
public class B {
public void f3(A a) { a.f2(); }
}
The key here is that we are passing an instance of A to B.f3. The way that we achieve that is by passing the this reference, which is a reference to the currently executing instance. In A.f1, that would be the instance of A that is currently executing.
You need an instance of class A to do this.
public class A{
private B b = new B();
public void f1(){
b.f3(this);
}
public void f2(){
// do smthing;
}
}
public class B{
public void f3(A a){
a.f2(); // Call f2 of class A from here.
}
}
This type of code structure is usually more confusing than useful. I suggest instead doing this.
public class A{
private B b = new B();
public void f1(){
WhatAf2Needs w = b.f3();
f2(w);
}
public void f2(WhatAf2Needs w){
// do smthing;
}
}
public class B{
public WhatAf2Needs f3(A a){
return WhatAf2Needs;
}
}
If you want to call a method of the thing that called you, you have to have the caller pass itself in using the this keyword. In code, it would be:
public class A{
private B b = new B();
public void f1(){
b.f3(this);
}
public void f2(){
// do smthing;
}
}
public class B{
public void f3(A caller){
caller.f2();
}
}
You would have to instantiate class A in class B, given the way it's currently written, to make any method calls on it.
You can also declare f2 static and call it like A.f2(). This type of things depend a lot on the design of your classes though. The other answers here are very valid too.
public class A{
private B b = new B();
public void f1(){
b.f3();
}
public static void f2(){
// do smthing;
}
}
public class B{
public void f3(){
A.f2();
}
}

String concatenation in inherited class

I have a class called A and there's a String declared in it. And i have 2 other classes B and C which is inherited from A
public abstract class A {
protected String ss="";
public abstract String someMethod();
}
public class B extends A{
public String someMethod(){
int i=8;
return ss+="$"+i;
}
}
public class C extends A {
public String someMethod() {
int i=9;
return ss+="$"+i;
}
}
Test Code:
A aa = new B();
aa.someMethod();
A aaa = new C();
aaa.someMethod();
When I print aaa.someMethod(); - why haven't the strings from class B and C been appended? I want them to be appended. How can I do this ?
/usr/lib/jvm/java-1.7.0-openjdk-amd64/bin/javac A.java B.java C.java Test.java
/usr/lib/jvm/java-1.7.0-openjdk-amd64/bin/java Test
$8
$9
nothing surprising here, B method someMethod() calls B method, C method someMethod() calls C method...
file A.java:
public abstract class A
{
protected String ss="";
public abstract String someMethod();
}
file B.java
public class B extends A
{
public String someMethod()
{
int i=8;
return ss+="$"+i;
}
}
file C.java
public class C extends A
{
public String someMethod()
{
int i=9;
return ss+="$"+i;
}
}
file Test.java
public class Test
{
public static void main(String pArgs[])
{
A aa = new B();
System.out.println(aa.someMethod());
A aaa = new C();
System.out.println(aaa.someMethod());
}
}
Overridden methods in Java do not automatically invoke their superclass parents. So, in your C subclass, calling someMethod does not invoke the method from its parent A, unless you explicitly call super.
public class C extends A
public String someMethod(){
int i=9;
return ss+= super.someMethod()+"$"+i;
}
}
I assume you are doing this to learn, because otherwise this is a pretty terrible way to manage your inherited classes and their properties.

java class A extends class B, and method override

public class A {
protected ClassX a;
public void foo() {
operations on a;
}
}
public class B extends A {
private ClassY b; // ClassY extends ClassX
#Override
public void foo() {
//wanna the exact same operation as A.foo(), but on b;
}
}
Sorry for such a not clear title.
My question is: in class B, when I call foo(), and I want the exact same operation as class A have on a. How do I achive that and without duplicate the same code from A?
If i leave out foo() in class B, would it work?
Or whats happening when I call super.foo() in foo();
Since ClassY extends ClassX, then you can remove private ClassY b from class B. Then you can just set your instance of ClassX to the a instance variable. This allows foo() to be inherited in class B, but still use the same logic and instance variable.
public class A {
protected ClassX a
public void foo() {
// operations on a;
}
}
public class B extends A {
// do something to set an instance of ClassY to a; for example...
public void setClassY(ClassY b){
this.a = b;
}
}
It sounds like ClassX and ClassY would have a common interface (if they have the same methods you want to call on earch, at least). Have you considered making foo() take in an object of the type of the common interface?
public class A {
private ClassX a;
protected void foo(ClassXAndClassYInheritMe anObject) {
operations on anObject;
}
public void foo() {
foo(a);
}
}
public class B {
private ClassY b;
#Override
public void foo() {
foo(b);
}
}
Don't define the foo() method in B if you want the same operation as that in A. If you want a different operation as A, override the foo() method in B. If you want to extend the foo() method in B so that it first does the operation in A and then in B, then call super.foo() at the top of the method; if you want the operation in A to come after the one in B, then call super.foo() at the end of the method foo().
You can do super.foo() inside your overrided method.

Categories