Class Design - Avoiding redundant code - java

I have a class A extending class B .
My class B has 5 abstract methods. In all these 5 methods , I need to make one call each to a methodA() . The problem with this is that since I need to create around lets say 40 classes which extend classB , I need to write same calls for methodA , 5 times per class and in all those 40 classes.
SO I end up writing calls to methodA , around 200 times.
Now how can I design this such that I don't need to make these calls at child class level?
Example below
The methodA here is a method which logs User's action in the database.
So each time I create a class extending class B, in all the 5 abstract methods I need to call a methodA which logs user's action in database.
Thanks

You can use a pattern like this:
abstract public class B {
/** Override to implement the subclass logic */
abstract protected SomeClass reallyCalculateStuff();
/** The public API method to be called by clients of the class */
final public SomeClass calculateStuff() {
executeSharedCode();
return reallyCalculateStuff();
}
/** The method all other methods need to call */
private void executeSharedCode() {
// ...
}
}
public class A extends B {
#Override
protected SomeClass reallyCalculateStuff() {
// ...
}
}
You obviously would want to come up with better names. But the idea is that the base class already contains the public API and takes care of calling the shared method.
This will also work if executeSharedCode needs to be implemented differently in every subclass. Just make it abstract as well.
However, depending on the usecase, there might be better alternatives to this. For example, interceptors. It might also be worth to rethink the design as this pattern could be perhaps avoided by designing classes differently. But all those things are impossible to judge without context, so I'll just give you this pattern.

If you want to reduce code copying, you can make the methods in B non-abstract and give them method bodies. This will mean that they aren't abstract any more, but since all subclasses will inherit this behavior you can still rest assured they will all be able to use the method. Thus, the methods in B can call methodA(), even if methodA is defined in the subclasses, and they can also be overridden by your subclasses if they need unique behavior.

Unfortunately, there's no way to intrinsically call the body of the parent class' method. You'll need to be a bit explicit about it using super.
Your parent class:
public class B {
public methodA() {}
public firstMethod() {
methodA();
}
}
Your implementation:
public class A extends B {
public firstMethod() {
super.firstMethod();
// method body
}
}
So, you still have to call super.firstMethod in your implementation, but at least this way, you can have a more extensive default implementation than a single method call.

Related

Why do we need abstract methods?

I have been studying abstract methods lately and I can't understand why do we need them?
I mean, after all, we are just overriding them. Do you know its just a declaration? Why do we need them?
Also, I tried understanding this from the internet and everywhere there's an explanation like imagine there's an abstract class human then there're its subclasses disabled and not disabled then the abstract function in human class walking() will contain different body or code. Now what I am saying is why don't we just create a function in the disabled and not disabled subclasses instead of overriding. Thus again back to the question in the first paragraph. Please explain it.
One of the most obvious uses of abstract methods is letting the abstract class call them from an implementation of other methods.
Here is an example:
class AbstractToy {
protected abstract String getName();
protected abstract String getSize();
public String getDescription() {
return "This is a really "+getSize()+" "+getName();
}
}
class ToyBear extends AbstractToy {
protected override String getName() { return "bear"; }
protected override String getSize() { return "big"; }
}
class ToyPenguin extends AbstractToy {
protected override String getName() { return "penguin"; }
protected override String getSize() { return "tiny"; }
}
Note how AbstractToy's implementation of getDescription is able to call getName and getSize, even though the definitions are in the subclasses. This is an instance of a well-known design pattern called Template Method.
The abstract method definition in a base type is a contract that guarantees that every concrete implementation of that type will have an implementation of that method.
Without it, the compiler wouldn't allow you to call that method on a reference of the base-type, because it couldn't guarantee that such a method will always be there.
So if you have
MyBaseClass x = getAnInstance();
x.doTheThing();
and MyBaseClass doesn't have a doTheThing method, then the compiler will tell you that it can't let you do that. By adding an abstract doTheThing method you guarantee that every concrete implementation that getAnInstance() can return has an implementation, which is good enough for the compiler, so it'll let you call that method.
Basically a more fundamental truth, that needs to be groked first is this:
You will have instances where the type of the variable is more general than the type of the value it holds. In simple cases you can just make the variable be the specific type:
MyDerivedClassA a = new MyDerivcedClassA();
In that case you could obviously call any method of MyDerivedClassA and wouldn't need any abstract methods in the base class.
But sometimes you want to do a thing with any MyBaseClass instance and you don't know what specific type it is:
public void doTheThingsForAll(Collection<? extends MyBaseClass> baseClassReferences) {
for (MyBaseClass myBaseReference : baseClassReferences) {
myBaseReference.doTheThing();
}
}
If your MyBaseClass didn't have the doTheThing abstract method, then the compiler wouldn't let you do that.
To continue with your example, at some point you might have a List of humans, and you don't really care whether they are disabled or not, all you care about is that you want to call the walking() method on them. In order to do that, the Human class needs to define a walking() method. However, you might not know how to implement that without knowing whether the human is or isn't disabled. So you leave the implementation to the inheriting classes.
There are some examples of how you'd use this in the other answers, so let me give some explanation of why you might do this.
First, one common rule of Object Oriented Design is that you should, in general, try to program to interfaces rather than specific implementations. This tends to improve the program's flexibility and maintainability if you need to change some behavior later. For example, in one program I wrote, we were writing data to CSV files. We later decided to switch to writing to Excel files instead. Programming to interfaces (rather than a specific implementation) made it a lot easier for us to make this change because we could just "drop in" a new class to write to Excel files in place of the class to write to CSV files.
You probably haven't studied this yet, but this is actually important for certain design patterns. A few notable examples of where this is potentially helpful are the Factory Pattern, the Strategy Pattern, and the State Pattern.
For context, a Design Pattern is a standard way of describing and documenting a solution to a known problem. If, for example, someone says "you should use the strategy pattern to solve this problem," this makes the general idea of how you should approach the problem clear.
Because sometimes we need a method that should behave differently in its instances.
For example, imagine a class Animal which contains a method Shout.
We are going to have different instances of this Animal class but we need to implement the method differently in some cases like below:
class Animal:
/**
different properties and methods
which are shared between all animals here
*/
...
method shout():
pass
class Dog extends Animal:
method shout():
makeDogVoice()
class Cat extends Animal:
method shout():
makeCatVoice()
dog = new Animal
cat = new Animal
dog.shout()
cat.shout()
So dog shouts like dogs, and cat shouts like cats! Without implementing the shared behaviors twice
There is a different behavior of shouting in these instances. So we need abstract classes.
Suppose you don't know about implementation and still want to declare a method then we can do that with the help of abstract modifier and making it an abstract method. For abstract method only declaration is available but not the implementation. Hence they should end with ;
Example:
public abstract void m1(); // this is correct
public abstract void m1(){ ... } // this is wrong
Advantage: By declaring abstract method in parent class we can provide guideline to child classes such that which methods are compulsory to implement.
Example:
abstract class Vehicle{
abstract int getNoOfWheels();
}
Class Bus extends Car{
public int getNoOfWheels(){
return 4;
}
}
If you want the short answer, think of this:
You have an abstract class Car.
You implement 2 classes that extend it, Ferrari and Mercedes.
Now:
What if you did one of the following, for the method drive(), common to all cars:
1) changed the visibility of the method,
2) changed the name of the method from driving to Driving,
3) changed the return type, from a boolean to an int
Think about it. It might not seem to make any difference right, because they are different implementations?
Wrong!
If I am iterating through an array of cars, I would have to call a different method for each type of car, thereby making this implementation of abstract useless.
Abstract classes are there to group classes with a common template, that share common properties. One way this helps would be the looping over the array:
Abstract methods ensure that all cars declare the same method,
and therefore, any object of a subclass of Car will have the method drive(), as defined in the abstract class, making the for loop mentioned easy to implement.
Hope this helps.

Refactoring and avoiding code duplication

I've ran into a problem that is new for me. Basically, someone else has already written a class A. The important parts looks like this
class A{
// some instance variables
public A(){
// Calls methods
build();
// Calls more methods
}
private build(){
item = makeItem();
anotherItem = makeAnotherItem();
// more code
}
private makeItem(){
// Does some things and calls updateItem()
}
private updateItem(){
// Does some things with instance variables of class A
// and calls yet another method in class A.
}
My problem is that build() does exactly what I need, but I need it in another class. Now here are the problems:
class A does a whole lot more than the things I've written, and so I cannot create an object of it. It would be pointless.
I've tried copying the build() method for my class B. However, build() uses other methods. And so I have to copy them as well and of course they call other methods and use instance variables declared in some other methods. Basically, I would have to copy 200 rows of code.
I'm guessing this problem actually has a name but I do not know what it's called and have therefore searched some basic terms only. What can I do to use build() in my class B?
You use the code of the build method in two classes but inheritance is not useful? Then you can reuse the code of the build method with composition. (hint Favor Composition over Inheritance) Create a new class C, which contains the build method. The class C is used by the classes A and B via composition. They delegate to the build method of the class C.
See the refactoring method of Martin Fowler.
https://sourcemaking.com/refactoring/smells/duplicate-code
also see
https://sourcemaking.com/refactoring/replace-inheritance-with-delegation
Always refactor in small steps. e.g. Put stuff together that belongs together, perhaps there is a neccessity for another class C which contains makeItem, makeAnotherItem and the corresponding instance variables. There is no general answer and it depends on how your code exactly looks like
first of all if build() in class A is using other private methods of A, that smells like you will need class A itself.
One option could be to create abstract class containing the common methods (including the build method), and extend this abstract class by class A and B. that way you will not have duplicate code
If for some reason you don't want to touch class A, I suggest you create an interface like :
public interface Builder{
void build()
}
and then implement this interface by your class B, and also extend class A so that you have implementation of the build method.
public class B extends A implements Builder{
// build() of class A will be used
// do other staff
}
In doing so, there is no change to class A at all (this might be desired if it is legacy code or something) + Builder can be used as a type in API you want to expose.

Why does this not override the class constructor?

public class ExtAA extends AA {
static int iTime;
public static void main(String argv[]) {
ExtAA d = new ExtAA();
d.func(iTime);
}
public static void func(int iTime) {
System.out.println(iTime);
}
public ExtAA() { }
}
class AA {
public AA() { System.out.println("AA"); }
}
prints:
AA
0
I would have expected public ExtAA() { } to override the constructor for AA and thus not print AA, just 0. Could someone explain in what way I am wrong, and if I'd want to override the constructor how could I ?
P.S. It is completely possible that my question is stupid, but I don't get what public ExtAA() { } should or could do. This was at a test, I messed up and I'd like to know what's actually happening (yes, I did go into debug and go over it step by step, I just don't know why new ExtAA uses AA instead of it's own defined constructor)
Constructor of super class in Java is always called. You can't stop that. You can just control which constructor is called if there are more of them.
Please consider reading some basic tutorial of Java, this is elementary thing of Java OOP.
Implicitly your constructor looks like this:
public ExtAA() {
super(); // Constructor of super class call, always first line of code in child constructor
}
An object has the fields of its own class plus all fields of its parent class, grandparent class, all the way up to the root class Object. It's necessary to initialize all fields, therefore all constructors must be called! The Java compiler automatically inserts the necessary constructor calls in the process of constructor chaining, or you can do it explicitly.
Imagine if you could skip a constructor from a base. It could leave the parent part of an object in an extremely unstable state.
Think about a situation where a base class does some kind of meaningful initialization in the constructor. If that doesn't get done, then suddenly the base class part of your object is in crazy-town. This is almost certainly why Java decided to work like this.
As a super trivial example, imagine if you had a SortedArrayList class that extends ArrayList. If SortedArrayList somehow didn't call any of the ArrayList constructors, do you think the internals of the object would make sense? Somewhere there would be a nulled out data structure meaning things would crash and burn. In certain situations it might make sense to override a constructor, but apparently the Java people felt that the risk of accidentally doing it wasn't worth the ability (and it very rarely makes sense in a well designed class graph -- if the child class doesn't depend on the base class in some way, then why is it a child class to begin with?).

Why java doesn't allow to make an instance method of parent class as more restrictive in child class

Polymorphism allows the programmer either to inherit, override or to overload an instance method of Parent Class.
But, it won't allow to make an instance method of parent class as more restrictive in child class. i.e it wont allow to use same name of parent class instance method, to declare as private in the child class.
Also JVM identifies the parent class version of an instance method, if child class didn't override it.
Similarly why don't JVM identifies the parent class version of an instance method, if the child class makes it more restrictive?
The more restrictive method of parent class in child class can be considered as child class specific method instead of overridden method by compiler.
This is all done in order to follow the Liskov Substitution Principle.
In order for inheritance in object oriented programming to behave as expected, a child class should be able to be substituted out for a parent class instance and not break a user of the class.
Making a child method more restrictive is basically saying "I don't want this method to be visible". Having the JVM automatically substitute out the parent class implementation in this case would just add a huge amount of confusion - just changing the call behavior might cause very unexpected behavior, even completely within the child class...
The more restrictive method of parent class in child class can be considered as child class specific method
Java authors could've implemented this. And many other things, like infamous multiple inheritance. But it would make language more complex for a very little benefit.
If you need a private version of parent's method, why don't you just give it different name? Since it'll be called from your child class only, there won't be much difference.
Java creators decided that Java should be as simple as possible, your question could cause problems with codes like this :
class A {
public void methodA(){
}
}
class B extends A {
#Override
private void methodA(){
}
}
//
public static void main(String... args){
A a = new B();
a.methodA(); // Should call the overridden method but as it's private it can't work.
}
You provided a solution for this case, but it as has a flaw :
class A {
public void methodA(){
}
public void methodB(){
methodA();
}
}
class B extends A {
#Override
protected void methodA(){
}
}
//
public static void main(String... args){
A a = new B();
a.methodB(); // Will methodA from A be called or from B ?
}
There the solution is complicated and against the java philosophy. That's more or less why the current solution is used; more simple even if a specific feature can't be used.
If I understand you correctly, you're saying that I should be able to write:
public class Foo
{
public int bar()
{
return 1;
}
}
public class Foo2 extends Foo
{
private int bar()
{
return 2;
}
public int barBar()
{
return bar();
}
}
public static void main(String[] args())
{
Foo2 foo2=new Foo2();
System.out.println(foo2.bar());
System.out.println(foo2.barBar());
}
Then if I create an instance of type Foo2 and call bar from within the class, it should call Foo2.bar so I should get back 2, but if I call bar from outside the class, it should call Foo.bar so I get back 1.
That is, the output of the above program should be:
1
2
Well, as this is a question about the design of the language, I guess the simple answer is, "Because that's how the designers of Java decided to do it."
The real question is, Why would you want it to behave the way you describe? Do you have an application where this would be useful? It seems to me that it would just be confusing.
What you want to do is wrap the "parent" class into another using composition, not inheritance when you want to restrict access.
So you create a new class having the class you want to wrap as member and provide access to what you want by designing your own API. Of course, you cannot use the new class in place ot the old one, but that wouldn't make any sense. If that is not want you want to do, I agree 100% with Reed Copsey's answer (I agree 100% even if that is what you wanted to do).

Can a Parent call Child Class methods?

Referring here
A is a precompiled Java class (I also have the source file)
B is a Java class that I am authoring
B extends A.
How can logic be implemented such that A can call the methods that B has.
The following are the conditions:
I don't want to touch A(only as a
last option though that is if no
other solution exists).
I don't want to use reflection.
As stated, if needed I could modify A.
What could be the possible solution either way?
Class A should define the methods it's going to call (probably as abstract ones, and A should be an abstract class, per Paul Haahr's excellent guide); B can (in fact to be concrete MUST, if the method are abstract) override those methods. Now, calls to those methods from other methods in A, when happening in an instance of class B, go to B's overrides.
The overall design pattern is known as Template Method; the methods to be overridden are often called "hook methods", and the method performing the calls, the "organizing method".
Yes it seems that if you override the super/base-classes's functions, calls to those functions in the base class will go to the child/derived class. Seems like a bad design in my opinion, but there you go.
class Base
{
public void foo()
{
doStuff();
}
public void doStuff()
{
print("base");
}
}
class Derived extends Base
{
#Override
public void doStuff()
{
print("derived");
}
}
new Derived().foo(); // Prints "derived".
Obviously all of Derived's methods have to be already defined in Base, but to do it otherwise (without introspection) would be logically impossible.
I would be rather hesitant to do this. Please correct me if I am wrong and then I will delete, but it sounds like you want to maintain an A object along with a B object. If they indeed are not the same object, the "tying together" (that's a scientific term) you'll have to do would be pretty ugly.

Categories

Resources