I am in a situation as follows.
I have an interface A which is inherited by class B,C,D (B,C,D implements A).
public interface A{
public String someMethod();
}
class B implements A{
ObjectType1 model;
#Override
public String someMethod(){
if(model instanceof X){
System.out.print(true);
}
}
}
class C implements A{
ObjectType2 model;
#Override
public String someMethod(){
if(model instanceof X){
System.out.print(true);
}
}
class D implements A{
ObjectType3 model;
#Override
public String someMethod(){
if(model instanceof X){
System.out.print(true);
}
}
As you can see all method implementations are the same. So I am duplicating code. My plan was to move the method to A and make A an abstract class. But the problem is my method depends on the model field. So what would be my options to make this code better?
bdw class A,B,C extends and implements other classes too.
EDIT
modification in code. check field
I don't see any problem related to the model field transforming the interface A into an abstract class.
There is no need to reimplement the method in the subclasses if it is the same, unless you want to change its behavior (override it).
public abstract class A {
// Make it protected so it can accessible by subclasses
protected Object model;
// Common behavior that will be inherited by subclasses
public String someMethod() {
if (model instanceof X) {
return "x";
} else {
return "not x";
}
}
}
public class B extends A {
// Subclasses may access superclasses fields if protected or public.
public void someOtherMethod() {
System.out.println(super.model.toString());
}
}
public class C extends A {
// You may wish to override a parent's method behavior
#Override
public String someMethod() {
return "subclass implements it different";
}
}
For your new code example, if you really want to do that in a procedural way you can create an abstract superclass ObjectType and then it will be accessible for the parent as well.
However I wouldn't do that. It seems to me that in doing so is the very opposite of what object orientation tries to solve.
By using a subclass to define the behavior, you wouldn't need to do it in a procedural logic. That's precisely then point of using objects, inheritance and overriding/implementing behavior as needed.
Create a parent class A with said field, and said function. Have the other classes extend A. No need to override them if they function the same.
To deduplicate, you can either make A an abstract class and move the implementation of the method and the field there, or create an abstract class, say E, that implements the interface with that method and field and then have B, C and D extend that class E.
For the more general question of depending on a subclass's field, you can create an abstract method getModel which the subclasses decide how to implement -- by returning a model field or doing something else.
If you are using java 8 you could use default method in interface A, with a getter method for model.
public interface A{
default public String someMethod() {
if(getModel() instanceof X){
System.out.print(true);
}
}
public Object model getModel();
}
Then implement getModel method in all child interfaces.
If you're going to do this you must have model to be of the same (basic) type in all derived objects. If it were of the same type there's a case for putting the model to a base class. Anyway if they are of different derived types you would need to have an accessor to get it.
interface B {
BaseModel getModel();
default public strict doSomething() {
BaseModel m = getModel();
// do something with m
}
}
class D implements B {
DerivedModel model;
public getModel() {
return model;
}
}
If I was given a chance to refactor it, I will follow below approach, leveraging Java 8 Default Methods:
interface A {
default String someMethod(X objectType) {
if (objectType instanceof X) {
System.out.println(true);
}
// return something, for now returning class
return objectType.getClass().toString();
}
}
class B implements A {
#Override
public String someMethod(X objectType) {
if (objectType instanceof X) {
System.out.println(true);
}
// return "Hello"
return "Hello";
}
}
class C implements A {}
class D implements A {}
Usage:
public class Main implements A {
public static void main(String[] args) {
B b = new B();
C c = new C();
D d = new D();
Main main = new Main();
main.call(b);
main.call(c);
main.call(d);
}
public void call(A clazz) {
ObjectType1 objectType1 = new ObjectType1();
String type = clazz.someMethod(objectType1);
System.out.println(type);
}
}
interface X {
}
class ObjectType1 implements X {
}
Related
Hey you people out there,
I'm asking myself the following question. This should be done in Java, but since I don't know how to do it anyway just a concept would help too:
I have the following code:
public abstract class A {
protected enum AType implements AInterface {
A_VALUE
}
public AInterface[] possibleRequests() {
AInterface types = AType.values();
return ArrayUtils.concat(types, possibleFurtherRequests());
}
public abstract AInterface[] possibleFurtherRequests();
}
public class B extends A {
protected enum BType implements BInterface {
B_VALUE
}
#Override
protected AInterface[] possibleFurtherRequests() {
//Here is my problem.
return BType.values();
}
}
public interface AInterface {
}
public interface BInterface extends AInterface {
}
What I want to do is have these possibleRequest-methods in indefinite depth. They should only be accessible via A, I do not and should not know which class the object of type A belongs to.
What I mean by indefinite depth is, that say this concept was extended with C extends B. I now want to access all values from A, B and C. How do I enforce, that whenever a new subclass is added the programmer is forced to define these AInterface-enumerations (optional) and how do I force him to implement a method that is then called recursively up the class Hierarchy (not optional).
I don't need help defining an abstract method, or overriding one. What I want to do is NOT override the existing one and NOT add an abstract method to each inheriting class that gets called.
I honestly don't know how to ask this question but I hope someone out there understands what I mean.
If not leave a comment.
Visibility of the methods is important. You can't force the subclasses to implement the now NOT abstract possibleFurtherRequests, but that is the only method they need. You also can't force them to call the super method either. Code reviews work nicely for that.
protected enum AType implements AInterface {
A_VALUE
}
protected enum BType implements BInterface {
B_VALUE
}
public abstract class A {
final public AInterface[] possibleRequests() {
return possibleFurtherRequests();
}
protected AInterface[] possibleFurtherRequests() {
return AType.values();
}
protected AInterface[] combine(AInterface[] some, AInterface[] more) {
AInterface[] combined = new AInterface[some.length + more.length];
System.arraycopy(some, 0, combined, 0, some.length);
System.arraycopy(more, 0, combined, some.length, more.length);
return combined;
}
}
public class B extends A {
#Override
protected AInterface[] possibleFurtherRequests() {
return combine(super.possibleFurtherRequests(), BType.values());
}
}
public interface AInterface {
}
public interface BInterface extends AInterface {
}
public void test() {
AInterface[] result = new B().possibleRequests();
Stream.of(result).forEach(System.out::println);
}
And the result is
A_VALUE
B_VALUE
I've got next situation:
There is an abstract class
public abstract class SuperClass {
public abstract void getString();
public abstract void method2();
}
public class InheritClass1 extends SuperClass {
#Override
public void getString(){...};
#Override
public void method2(){...};
}
public class InheritClass2 extends SuperClass {
#Override
public void getString{...};
#Override
public void method2(){...};
public void customMethod(){...};
}
There is another class that has a method that accepts SuperClass object as an argument. Depending on what kind of String is returned from getString I perform different actions. My case is that I am trying to call a child method while the object is of parent class:
public class Processor {
public String method(SuperClass type) {
switch (type.getString()) {
case "1":
return "OK"
case "2":
return ((InheritClass2) type).customMethod()
}
}
I do understand that this is BAD DESIGN, could you please help me with finding the best solution for this problem. Maybe generics are suitable in this case somehow. Also the thing is that customMethod() should be a part of not all classes.
Since only some (sub)classes implements customMethod, I would suggest to create an interface that contains this method:
public interface CustomInterface {
public String customMethod();
}
Your SuperClass can then remain just as it is. Only the subclasses/child classes that have customMethod, would then extend your SuperClass as well as implement this CustomInterface. This way, the child classes that do not implement CustomMethod (does not have the method in their class, such as InheritClass1 in your example), also remain just as they are.
Only child classes that have CustomMethod, such as InheritClass2 would then need to change slightly by saying it implements this new interface:
public class InheritClass2 extends SuperClass implements CustomInteface {
// the rest stays the same
}
Then in the section where you want to do the casting, you rather do the following:
public class Processor {
public String method(SuperClass type) {
switch (type.getString()) {
case "1":
return "OK"
case "2":
String s = "";
if (type instance of CustomInterface) {
s = (CustomInterface type).customMethod();
}
return s;
}
}
}
Using the interface in this way will help that you can implement all child classes and not just one as implementing the CustomInterface, and thus, all child classes will work with using instanceof and casting to the interface to call customMethod() - you won't have to handle each child that needs this method separately.
NOTE: Your code is clearly simplified example, it is unclear if the getString() method is just returning an identifier of the child classes in order for you to know which ones you can cast and then call custom Method on... If this is the purpose of your switch and getString methods - to identify which types implement the customMethod() and to call that method, and for any child class that does not have that method to return just "OK" - then you could instead do the following:
public class SubClass1 extends SuperClass implements CustomInterface {
// other mehtods...
public String CustomMethod() { return "SomeString1"; }
}
public class SubClass2 extends SuperClass {
// other methods...
// this subclass does not have the CustomMethod()
}
public class SubClass3 extends SuperClass implements CustomInterface {
// other methods...
public String CustomMethod() { return "SomeString3"; }
}
Then your Processor could look like this:
public class Processor {
public String method(SuperClass type) {
return (type instanceof CustomInterface) ? ((CustomInterface) type).CustomMethod() : "OK";
}
public static void main(String[] args) {
Processor p = new Processor();
SuperClass obj1 = new SubClass1();
SuperClass obj2 = new SubClass2();
SuperClass obj3 = new SubClass3();
System.out.println(p.method(obj1)); // prints: "SomeString1"
System.out.println(p.method(obj2)); // prints: "OK"
System.out.println(p.method(obj3)); // prints: "SomeString3"
}
}
If you don't understand the ternary operator then you can read about it here That's the condition ? exprTrue : exprFalse syntax. It's a short if else statement basically.
You can create an interface, with default custom method implementation, like:
interface A {
default String customMethod() {
return "";
}
}
And abstract class will implement this interface:
public abstract class SupperClass implements A {
public abstract String getString();
public abstract void method2();
}
Bad design will cause you to get bad answers. If you don't want to cast your object to a child object. You could use reflection.
import java.lang.reflect.Method;
public class Processor {
public String method(SuperClass type) {
Method[] methods = type.getClass().getMethods();
for (Method m : methods) {
if (m.getName().equals("customMethod")) {
try {
return m.invoke(type);
} catch (Exception ex) {
// throw
}
}
}
return "OK";
}
}
Depending on your design you could apply:
if (type instanceof InheritClass2.class) return type.customMethod();
or
if (type.getClass() == InheritClass2.class) return type.customMethod();
I have three classes:
Base extends Object
Derived1 extends Base
Derived2 extends Derived1
Each of the classes has its own fields which should be cloned. And I have troubles with understanding the best way to implement clone and avoid duplicating code. I have a the following architecture, but it looks like worst to me
Derived2.clone(): it calls super.clone() and receives an object of Derived1. Then it calls the new Derived2(objOfDerived1) which calls super(objOfDerived1) which copies all of its fields and after that in Derived2.clone() all the fields of Derived2 are copied.
How would you say to this? Maybe there are any articles which describe this problem?
UPD: the idea can be shown here
class Base implements Cloneable {
private String dataOfBase;
public Base() {
}
public Base(Base base) {
this.dataOfBase = base.dataOfBase;
}
#Override
public Object clone() {
Base base = new Base();
base.dataOfBase = dataOfBase;
return base;
}
}
class Derived extends Base {
private String dataOfDerived;
public Derived(Base base) {
super(base);
}
#Override
public Object clone() {
Base base = super.clone();
Derived derived = new Derived(base);
derived.dataOfDerived = dataOfDerived;
return derived;
}
}
You could implement clone in terms of the copy constructor:
class Base {
private String dataOfBase;
...
public Base(Base other) {
this.dataOfBase = other.dataOfBase;
}
#Override
public Base clone() { // Covariant return type
return new Base(this); // calling copy constructor
}
}
class Derived extends Base {
private String dataOfDerived;
...
public Derived(Derived other) {
super(other);
this.dataOfDerived = other.dataOfDerived;
}
#Override
public Derived clone() {
return new Derived(this);
}
}
What about something like this. It would allow you to clone any class in the hierarchy directly and include the data from all classes higher in the hierarchy.
public class Derived1 extends Base {
public Derived1 clone(Derived1 foo) {
super.clone(foo);
// copy fields from Derived1
return foo;
}
public Derived1 clone() {
Derived1 foo = new Derived1();
return this.clone(foo);
}
}
I wanted to implement a method in a abstract class that is called by the inherited classes and uses their values.
For instance:
abstract class MyClass{
String value = "myClass";
void foo(){System.out.println(this.value);}
}
public class childClass{
String value="childClass";
void foo(){super.foo();}
}
public static void main(String[] args){
new childClass.foo();
}
This will output "myClass" but what I really want is to output "childClass". This is so I can implement a "general" method in a class that when extended by other classes it will use the values from those classes.
I could pass the values as function arguments but I wanted to know if it would be possible to implement the "architecture" I've described.
A super method called by the inherited class which uses the values from the caller not itself, this without passing the values by arguments.
You could do something like this:
abstract class MyClass {
protected String myValue() {
return "MyClass";
}
final void foo() {
System.out.println(myValue());
}
}
public class ChildClass extends MyClass {
#Override
protected String myValue() {
return "ChildClass";
}
}
and so on
This is a place where composition is better than inheritance
public class Doer{
private Doee doee;
public Doer(Doee doee){
this.doee = doee;
}
public void foo(){
System.out.println(doee.value);
}
}
public abstract class Doee{
public String value="myClass"
}
public ChildDoee extends Doee{
public String= "childClass"
}
...
//Excerpt from factory
new Doer(new ChildDoee);
I believe you are asking whether this is possible:
public class MyClass {
void foo() {
if (this instanceof childClass) // do stuff for childClass
else if (this intanceof anotherChildClass) // do stuff for that one
}
}
So the answer is "yes, it's doable", but very much advised against as it a) tries to reimplement polymorphism instead of using it and b) violates the separation between abstract and concrete classes.
You simply want value in MyClass to be different for an instance of childClass.
To do this, change the value in the childClass constructor:
public class childClass {
public childClass() {
value = "childClass";
}
}
Edited:
If you can't override/replace the constructor(s), add an instance block (which gets executed after the constructor, even an undeclared "default" constructor):
public class childClass {
{
value = "childClass";
}
}
So I know that reference variables cannot be changed.
I'm in a position where I have two different classes. Let's call them A and B. They have the same methods (the methods are called the same) they're just specified for the class.
I need a clever way of changing between which classes to instantiate.
One way could be with some boolean tests checking which option has been selected and then instantiate the corresponding class. Although I fear that this might become bulky and ugly, so I'm trying to avoid this way. There must be something more clever.
Currently I'm thinking of making a new class (e.g. C) that extends the same class as A and B.
I would then override the methods (as class A and B also do btw) and then execute the methods depending on the setting (i.e. which class A or B is selected). The methods would return the same as it would in class A or B.
Hope I'm not talking complete gibberish.
One way to do this is to use the Factory Pattern.
Partial quote from Wikipedia:
Like other creational patterns, it
deals with the problem of creating
objects (products) without specifying
the exact class of object that will be
created.
E.g.
public abstract class Base {
public abstract void doSomething();
}
public class A extends Base {
public void doSomething() {
System.out.println("A");
}
}
public class B extends Base {
public void doSomething() {
System.out.println("B");
}
}
public class C extends Base {
public void doSomething() {
System.out.println("C");
}
}
public interface BaseFactory {
public Base createBase(int condition);
}
public class DefaultBaseFactory implements BaseFactory {
public Base createBase(int condition) {
switch (condition) {
case 0 : return new A();
break;
case 1: return new B();
break;
case 3: return new C();
break;
default: return null;
break;
}
}
}
Your explanation is confusing. But it sounds like you should extend A and B from a common base class (or an interface):
abstract class Base {
public abstract void someMethod();
}
class A extends Base {
public void someMethod() { System.out.println("A"); }
}
class B extends Base {
public void someMethod() { System.out.println("B"); }
}
That means you can do something like this:
Base base;
if (someCondition) {
base = new A();
}
else {
base = new B();
}
base.someMethod();