OOD: Code refactoring and best design (protected or getter/setter) - java

Reading the code for a project, I noticed this situation, there are two classes as the following example:
class A {
private class E aE;
private class F aF;
public A(){
aE = new E();
aF = new F();
}
public void foo1(){
aE.bar();
...
aF.poo();
}
}
class B implements Runnable {
private class E aE;
private class F aF;
public B(){
aE = new E();
aF = new F();
}
public void run(){
...
x = aE.bar()
...
}
}
I would refactoring this code in order to get a superclass A, but along this way it is better to make fields aE and aF protected in class A and use them in class B or add two methods in class A as getE() and getF() and use this method in class B ?

class B doesn't extend A, it appears to be a simple copy-paste job with the methods needed for implementing Runnable. You clearly should avoid that and make another class which sole purpose is running the application, you probably won't need class B after that.

Mark, From this example it is difficult to point out how you should refactor this code. Here are some possibilities -
Whether to have a common parent class for A and B depends upon whether there is an logical parent-child relationship between actual classes.
You can also extend class B from A if there is a relationship. You will have to expose aE and aF as public properties in that case.
Another possibility is you can implement Runnable on A itself, eliminating class B.
If it is very common to have both class E and F as private fields together, then you can consider encapsulating them in one type, say EF, and then compose other classes with that class.
However, the correct answer can be given only after knowing what the actual classes are.

Any statement about classes named 'A' and 'B' likely doesn't have enough context to be either wrong or right.
But I would, assuming a case in which it was reasonable to have a B extending A, almost always prefer to use protected or package-level data member access. If you have an interface that is formal and serious enough to use Get/Set accessors, you are probably outside the context in which implementation inheritance is a good design choice.

Related

Conflicting methods on interface multiple inheritance

I have the following interfaces (in Java, but it's more of an OO question, not language-specific, I'm interested in answers for any language)
public interface A {
int foo();
}
and
public interface B {
char foo();
}
If I now want to make the following class:
public class C implements A,B{
public int foo() {
return 0;
}
public char foo() {
return 0;
}
}
This won't compile because the methods are conflicting. Is there any way to make this work, or something with the same meaning (of course without modifying A or B, that would be trivial)?
No, the return type cannot be a deciding factor in making a method signature unique because you do not need to assign the returned value to anything, the compiler wouldn't know what to do in that case.
Concrete example:
...
C object = new C();
object.foo();
...
Which foo did I just call? Can't tell.
To make this work you'll need to have either different method names or different parameter types in the interface methods.
EDIT: assuming you have no control over the interfaces A and B (library classes or similar) this is the solution I'd take if I wanted to implement them in the same class:
public class C {
private objectA = new AImpl();
private objectB = new BImpl();
// Work with the objects here
private class AImpl implements A {
public int foo() {
// ...
}
}
private class BImpl implements B {
public char foo() {
// ...
}
}
}
The common solution is to give each method a different name. Avoid generic names that have a high chance of naming collision with another interface.
This problem is present because in OOP, is considered the existence of more one method with the same name but with different parameters and not by return type.
The problem is not the interface, the problem is the class.
Overloading comes with parameters.
There are several solutions to this problem in use. I am working on the assumption that these are independent interfaces, that the intention is multiple interface (implementation of two unrelated interfaces on the same object) and that overloading has nothing to do with it.
The solutions I am aware of are:
1. Scoping. A reference to foo() can be qualified as A.foo() or B.foo() to determine which is required.
1. Namespaces. The interfaces are inherited inside a namespace constructed for the purpose, and all references to foo() must be preceded by a namespace, eg A::foo(), B::foo().
1. Aliasing. One or both of the foo() methods are explicitly renamed when inherited. Calls become something like A_foo() and B_foo().
Ada certainly had a mechanism like this, and I think some variants of Pascal did too. I can find more examples if it's important.

Java: How do I add to a base class without modifying class file

I am using a Java library that has a class hierarchy:
e.g. classes C1 and C2 that both extend class B
Is there a way for me to add functionality (attributes, methods) to class B such that it will be available to the child classes C1 & C2 without modifying the 3 files?
If not, what is the right way to do this short of rewriting all 3 classes?
Assuming you aren't able to modify B for some reason, make an intermediary class that extends it for you:
public class ClassC extends ClassB {
//additional functionality
}
Then it's simple:
public class Class1 extends ClassC {...}
If you can modify B, the other classes already inherit the methods, and you don't need to worry about rewriting them unless you mark the methods abstract
If you cannot modify B then you will have to extend it, and modify C1 and C2 to extend your new class instead of B.
If you cannot modify any of these classes, then you could do something like this:
Create BX extending B with new functionality
Create C1X extending BX, and containing an inner C1 object. Delegate all method calls except the new methods in BX to the underlying C1 object
Create C2X following the same logic as C1X
This ain't pretty. And might not work. For example if the new method needs to manipulate private data of the underlying objects then this won't work. But I don't think there's another way, given the restrictions. If Java had multiple inheritance it could work by C1X extending both C1 and BX, but short of that I'm afraid this dirty solution is the best you can have. (If it even works.)
Is there a way for me to add functionality (attributes, methods) to class B such that it will be available to the child classes C1 & C2 without modifying the 3 files?
You will only have to modify the class B. If you add methods, they will be inherited by classes C1 and C2 automatically, so you don't need to modify those classes.
You only need to modify class B. If you add a protected or public method to B, C1 and C2 will automatically be able to invoke it, without any changes required.
Seems the question is kind of vague and it is hard to tell without knowing your intention.
If you want to enhance the behavior of your class in runtime, then you may look into something like Javassit or CGLib etc, which allow you to alter the classes and add new feature to it, without need of modifying source code of the original source.
If you are developing something, and trying to find a design that will allow you to add functionality without changing source code of existing classes, then you may look into things like Dectorator pattern.
If you simply have that three class on hand and you don't want to/not allowed to modify them but you still want to add functionality without updating them. Then it is not possible in Java, sorry. (A lot other languages provide such feature anyway)
You'll have to modify class B in any case. There can be 2 approaches to this(assuming you can modify B).
First: Make the changes you want to do in B directly and since C1 and C2 extend B already, the methods and fields would be available in those classes as such(only if they are public or protected, that is). This requires a lot of changing in B though.
Second: Have an abstract class which is extended by B. In this case, a small change to B should suffice which would be extending that abstract class. This way, everything you add to the abstract class is available to all the classes below in the hierarchy. Just make sure you don't have any abstract methods in the abstract class.
public abstract class ParentOfB {
// Additional functionality
}
public class B extends ParentOfB { // The only change in B
}
The reason why ParentOfB is abstract is because you don't want any other class using those functionality without inheriting B. In case you need that functionality elsewhere, you can make ParentOfB just a normal class.
This is the answer I came up with. It's a variation of what Janos wrote but I think it is nicer. I do not need to change any of the classes, can re-use the extension in any of the children classes and continue to inherit from the new extended children. Still need to delegate the methods though.
So for example:
Note how D1 below already inherits from B1, C1 and B_EXTRA_IMPL
public class B1 {
public void b1() {
System.out.println("B1");
}
}
public class C1 extends B1 {
public void c1() {
System.out.println("C1");
}
}
-------------------------- Adding New B1 Functionality to C1 ---------------------
public interface B_EXTRA {
void b_extra();
}
public class B_EXTRA_IMPL implements B_EXTRA {
public B1 m_b1;
B_EXTRA_IMPL(B1 base) {
m_b1 = base;
}
#Override
public void b_extra() {
System.out.println("b_extra");
}
}
public class C1X extends C1 implements B_EXTRA {
B_EXTRA_IMPL b_extra;
C1X() {
super();
b_extra = new B_EXTRA_IMPL((B1)this);
}
public void b1()
{
System.out.println("B1");
}
#Override
public void b_extra() {
b_extra.b_extra();
}
}
public class D1 extends C1X {
}
public class Main {
public static void main(String[] args) {
D1 d = new D1();
d.b1();
d.c1();
d.b_extra();
}
}
Just modify class B. No need for changes in other files.

Don't inherit private member if it's accessed by public member

I'm sorry if this question may be asked all the time, but I searched and couldn't find an sufficient answer.
How to disable inheritance of private members/fields if they are being accessed by a public member/method?
So consider this:
public class A {
private MemberA a = new MemberA();
public void foo(TypeA x) {
a.methodCall(); //access to a
}
}
public class B extends A {
private MemberB b = new MemberB();
public void foo(TypeB x) {
b.methodCall();
}
}
If you hit the debugger you'll see, that B has a field a by type MemberA. That's in compliance with Java rules because if a public member has access to a private member it will be inherited.
But in B "a" is useless and only taking memory - even if you don't instanciate it in the constructor of B, because B calls it's super constructor and it has to be instanciated in A because a has very much use for a.
I need to have same method names for A and B and they have to be public, but since they do fundamentally different things but also share common logic B needs to be inherited from A.
So basically, I need to know how to overload and override a method the same time. Or duplicate code. What to do?
This situation -- where a class has data members that you do not want to inherit -- is called the "Refused Bequest" antipattern, and what it generally means is that your inheritance relationship is wrong. Rather than having B extend A, you need an interface C that both implement independently. If there is significant implementation that you do want to share, then perhaps you could introduce an abstract base class that A and B could share.
Alternatively, it could also be that MemberA and MemberB (not A and B) share the common interface (or abstract class), say "Member", including methodCall(). You could then do
public class A {
protected Member myMember; // sounds like an Austin Powers movie...
// in the constructor
myMember= new A();
}
while, in class B, the constructor does this instead: (or use DI, etc...)
myMember = new B();
and in foo(), which need not be overloaded, you call myMember.methodCall().
Without knowing your problem it's hard to say if this approach or #Ernest's is better. In either case you are looking for common functionality, and it will likely be the same amount of work.

calling derived class method using base class object

I have 6 classes as shown in figure below.
Now, class A has an object of class B as a private variable defined. Also class A methods calls many methods from class B, for example B.method1().
Now, class A_Base1 is which is derived from class A, needs to call methods from the derived class B_Base1; for example B1.method2(). And also methods of class A_Base2 needs to call methods from class B_Base2; for example B2.method3().
Now in class A I define the variable as -
private B bObject
Now in method of A_Base1, I cannot cannot call the methods like bObject.method2() since its a base class object.
I need suggestions on -
Is it possible to call derived class object methods using base class object?
Or do I need to re-design this scenario in some other good way?
Using inheritance like this imo only makes sense if the Bx.methodX() do something that means she same to the different Ax. And in that case, you should name them that way:
public class B {
public void doWhatAMeans() {
method1();
}
public class B1 extends B {
#Override
public void doWhatAMeans() {
method2();
}
public class B2 extends B {
#Override
public void doWhatAMeans() {
method3();
}
and then you only need A to call doWhatAMeans() and the A1 and A2 only need to be injected the appopriate instances of Bx.
On the other hand, if doWhatAMeans does not make sense because the methodX do different things that mean different things to Ax, then you need to rethink your object model, probably the parallel structures A,A1,A2 and B,B1,B2 are wrong then.
you could always cast. suppose your class A provides this method:
protected B getBInstance() {
return bObject;
}
then in A_Base1 you could do something like:
((B_Base1)getBInstance()).method2();
this, however, is a VERY bad design. if your A_Base1 class needs an instance of B_Base1 it should be handed such an instance directly at construction time:
public class A_Base1 extends A {
private B_Base1 b1Object;
public A_Base1(B_Base1 instance) {
super(B_Base1); //works as a B for parent
this.b1Ovject = instance;
}
}
and then you can use that
since A is a parent of A_Base1 (I'm assuming extended) you can make the function call that Accesses B public (or protected) and then A_Base1 or A_Base2 can use the same function A does to call into B.

Passing a custom object in Java

I know this is probably pretty basic, and I'm ashamed for not knowing how to do this (and worse yet, being unsuccessful in searching for a solution).
How would I pass an object of type thing from A to C?
public class A extends B {
}
public class B {
public class thing {
}
}
public class C extends JFrame {
}
I have access to thing in A because I'm extending B, but I'm unable to extend B when using class C because I need to extend JFrame.
EDIT
Sorry for the vagueness. Class A has a collection of objects of type thing and I want to iterate through those objects in class C.
EDIT 2
And of course... the obvious choice. Make thing its own class... :(
Admitting shame for the sake of those who may also have an issue like this.
First, if it's an inner class - you probably shouldn't access it from the outside...
But, if you insist, you can try to do as follows:
public class A extends B {
}
public class B {
public class thing {
}
private thing mything = new thing();
public thing getThing(){
return mything;
}
}
public class C extends JFrame {
A a = new A();
Object thing = a.getThing();
}
accessing an inner class from the outside is generally a bad idea, but if you must i wold suggest looking at the delegate design pattern like in this article :
delegate design pattern
You probably trying to use multi-inheritance which is not possible in java!
you can use interfaces to have 2 different behavior or Use some design patterns
to achieve such a goal.
It's really unclear what you are trying to do.however see composite or factory-method patterns
i think it could help.

Categories