Why do we need abstract methods? - java

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.

Related

How to prohibit a subclass from having a method?

In my Java project, I have the method addType1AndType2() which has windows where you expand lists and select objects from the list. It was very complicated and time consuming to create, as things must be scrolled and xpaths keep changing. There are two lists in this which are actual names but, due to company proprietary info, I will just call them Tyep1 and Type2.
Now I have an UpdateType1 class which uses all the complicated methodology in the AddType1AndType2 but has nothing related to Type2 in it. I could copy the AddType1AndType2 and cut everything I do not need, but that would be replicating and changes would have to be duplicated in both classes. This defeats the purpose of inheritance and reusability.
I can make a class UpdateType1 extends AddType1AndType2{} which I have done. But there are still methods like selectType2Value() which are inherited but not possible in the subclass.
If I do an #Override and declare the class as private in the sub class, I get an error that I cannot reduce the visibility in a subclass.
Any idea what I can do? Right now I am just putting a throw new AssertError("Do not use") but that seems kind of lame. Is there a better thing to do that would even give a compile-time error rather than an assert at run time, or is this the best way?
The thing is: your model is wrong.
Inheritance is more than just putting "A extends B" in your source code. A extends B means: A "is a" B.
Whenever you use a B object, you should be able to put an A object instead (called Liskov substitution principle).
Long story short: if B has methods that A should not have ... then you should not have A extends B.
So the real answer is: you should step back and carefully decide which methods you really want to share. You put those on your base class. Anything else has to go. You might probably define additional interfaces, and more base classes, like
class EnhancedBase extends Base implements AdditionalStuff {
Edit: given your comment; the best way would be:
Create interfaces that denote the various groups of methods that should go together
Instead of extending that base class, use composition: create a new class A that uses some B object in order to implement one/more of those new interfaces.
And remember this as an good example why LSP really makes sense ;-)
Create the interfaces
public interface IAddType1 {... /* methods signtatures to add Type1 */}
public interface IAddType2 {... /* methods signtatures to add Type2 */}
public interface IUpdateType1 {... /* methods signtatures to update Type1 */}
then your current code at AddType1AndType2 will become just a base helper class:
public abstract class BaseOperationsType1AndType2{
//code originally at AddType1AndType2: methods that add Type1 and Type2
}
then your new AddType1AndType2 class will be:
public class AddType1AndType2
extends BaseOperationsType1AndType2,
implements IAddType1 , IAddType2 {
//nothing special.
}
and your new UpdateType1can be defined as
public class UpdateType1
extends BaseOperationsType1AndType2
implements IUpdateType1 {
//
}
Voila.
You can use 'final' keyword to prohibit extending a method in a subclass.
A method with a 'final' modifier cannot be overriden in a subclass.

Understanding Java Interfaces Principles

I am reading a Java book and stuck again this time thinking about what this whole paragraph actually means:
Interfaces are designed to support dynamic method resolution at run time. Normally, in order for a method to be called from one class to another, both classes need to be present at compile time so the Java compiler can check to ensure that the method signatures are compatible. This requirement by itself makes for a static and nonextensible classing environment. Inevitably in a system like this, functionality gets pushed up higher and higher in the class hierarchy so that the mechanisms will be available to more and more subclasses. Interfaces are designed to avoid this problem. They disconnect the definition of a method or set of methods from the inheritance hierarchy. Since interfaces are in a different hierarchy from classes, it is possible for classes that are unrelated in terms of the class hierarchy to implement the same interface. This is where the real power of interfaces is realized.
First question: what does the author mean by saying from one class to another? Does he mean that those classes are related in terms of the hierarchy? I mean, assigning subclass object reference to its superclass type variable and then calling a method?
Second question: what does the author again mean by saying This requirement by itself makes for a static and nonextensible classing environment? I don't understand the makes for meaning (english is not my main language) and why the environment is called static and nonextensible.
Third question: what does he mean by saying functionality gets pushed up higher and higher? Why does it get pushed up higher and higher? What functionality? Also, mechanisms will be available to more and more subclasses. What mechanisms? Methods?
Fourth question: Interfaces are designed to avoid this problem. What problem???
I know the answers must be obvious but I don't know them. Maybe mainly because I don't undestand some magic english phrases. Please help me to understand what is this whole paragraph telling.
Between any two classes. If your code contains a call to String.substring() for example, the String class and its substring() method must be available at compile time.
As said, "makes for" means the same as "creates". The environment is non-extensible because everything you may want to use must be available at compile time. (This isn't 100% true though. Abstract classes and methods provide extension points even when no interfaces are present, but they aren't very flexible as we're going to see.)
Imagine that you have two classes: Foo and Bar. Both classes extend the class Thingy. But then you want to add a new functionality, let's say you want to display both in HTML on a web page. So you add a method to both that does that.
The basic problem
abstract class Thingy { ... }
class Foo extends Thingy {
...
public String toHTMLString() {
...
}
}
class Bar extends Thingy {
...
public String toHTMLString() {
...
}
}
This is great but how do you call this method?
public String createWebPage( Thingy th ) {
...
if (th instanceof Foo)
return ((Foo)th).toHTMLString();
if (th instanceof Bar)
return ((Bar)th).toHTMLString();
...
}
Clearly this way isn't flexible at all. So what can you do? Well, you can push toHTMLString() up into their common ancestor, Thingy. (And this is what the book is talking about.)
A naive attempt to resolve it
abstract class Thingy {
...
public abstract String toHTMLString();
}
class Foo extends Thingy {
...
public String toHTMLString() {
...
}
}
class Bar extends Thingy {
...
public String toHTMLString() {
...
}
}
And then you can call it like this:
public String createWebPage( Thingy th ) {
...
return th.toHTMLString();
}
Success! Except now you've forced every class extending Thingy to implement a toHTMLString() method, even if it doesn't make sense for some of them. Even worse, what if the two objects do not extend anything explicitly, they're completely unrelated? You'd have to push the method up all the way into their common ancestor, which is java.lang.Object. And you can't do that.
Solution with interfaces
So what can we do with interfaces?
abstract class Thingy { ... }
interface HTMLPrintable {
public String toHTMLString();
}
class Foo extends Thingy implements HTMLPrintable {
...
public String toHTMLString() {
...
}
}
class Bar extends Thingy implements HTMLPrintable {
...
public String toHTMLString() {
...
}
}
//We've added another class that isn't related to all of the above but is still HTMLPrintable,
//with interfaces we can do this.
class NotEvenAThingy implements HTMLPrintable {
public String toHTMLString() {
...
}
}
And the calling code will be simply
public String createWebPage( HTMLPrintable th ) {
...
return th.toHTMLString(); // "implements HTMLPrintable" guarantees that this method exists
}
What are interfaces then?
There are many metaphors used to understand interfaces, the most popular is probably the idea of a contract. What it says to the caller is this: "If you need X done, we'll get it done. Don't worry about how, that's not your problem." (Although the word "contract" is often used in a more general sense, so be careful.)
Or in another way: if you want to buy a newspaper, you don't care if it's sold in a supermarket, a newsagents or a small stall in the street, you just want to buy a newspaper. So NewspaperVendor in this case is an interface with one method: sellNewsPaper(). And if someone later decides to sell newspaper online or door-to-door, all they need to do is implement the interface and people will buy from them.
But my favourite example is the little sticker in shop windows that says "we accept X,Y and Z credit cards". That's the purest real-world example of an interface. The shops could sell anything (they may not even be shops, some might be restaurants), the card readers they use are different too. But you don't care about all of that, you look at the sign and you know you can pay with your card there.
The Key to paragraph is "classes need to be present at compile time" in line 2. Classes are more concrete. While interfaces are abstract.
As classes are concrete so Designer and programmer needs to know all about class structure and how the methods are implemented. Where as interfaces are more abstract. (They contain abstract methods only). So programmer needs to know only what methods an interface has to have and signature of those methods. He does not need to know detail how these are implemented.
Thus using interfaces is easier and better while making subclasses. You only need to know method signatures of interface.
Using concrete class we have to implement functionality of a method high in class hierarchy while using interface avoids this problem. (There is a related concept of polymorphism that you would probably learn later)

Interface method referencing a concrete class as parameter causes coupling?

I was thinking about programming to interfaces and not to concrete classes, but I had a doubt: should any interface method be able to hold references to concrete classes?
Suppose the following scenarios:
1)
public interface AbsType1 {
public boolean method1(int a); // it's ok, only primitive types here
}
2)
public interface AbsType2 {
public boolean method2(MyClass a); // I think I have some coupling here
}
Should I choose a different design here in order to avoid the latter? e.g.
public interface MyInterface {} // yes, this is empty
public classe MyClass implements MyInterface {
// basically identical to the previous "MyClass"
}
public interface AbsType2 {
public boolean method2(MyInterface a); // this is better (as long as the
// interface is really stable)
}
But there's still something that doesn't convince me... I feel uncomfortable with declaring an empty interface, though I saw someone else doing so.
Maybe and Abstract Class would work better here?
I am a little bit confused.
EDIT:
Ok, I'll try to be more specific by making an example. Let's say I'm desining a ShopCart and I want of course to add items to the cart:
public interface ShopCart {
public void addArticle(Article a);
}
Now, if Article were a concrete class, what if its implementation changes over time? This is why I could think of making it an Interface, but then again, it's probably not suitable at least at a semantic level because interfaces should specify behaviours and an Article has none (or almost none... I guess it's a sort of entity class).
So, probably I'm ending up right now to the conclusion that making Article an abstract class in this case would be the best thing... what do you think about it?
I would use interfaces because composition is much better than inheritance. "Should any interface method be able to hold references to concrete classes ?", why it shouldn't? Some classes within package are coupled, it's a fact and common use technique. When you marked this relation in interface then you see on which classes is dependent your implementation. Dependency or composition relations are not inheritance so a i would avoid abstract class.
In my opinion Interfaces are fine for all types where the implementation may vary. But if you define a module which introduces a new type, that isn't intended to have alternative implementations then there is no need to define it as an Interface in the first place. Often this would be over-design in my opinion. It depends on the problem domain and often on the way how support testing or AOP-weaving.
For example consider a 2D problem domain where you need to model a Location as a type. If it is clear that a Location is always represented by a x and y coordinate, you may provide it as a Class. But if you do not know which properties a Location could have (GPS data, x, y, z coordinates, etc.) but you rely on some behavior like distance(), you should model it as an Interface instead.
If there are no public methods which AbsType would access in MyClass then the empty interface is probably not a good way to go.
There is no interface declaration (contract) for static methods, which otherwise might make sense here.
So, if AbsType is not going to use any methods from MyClass/MyInterface, then I assume it's basically only storing the class object for some other purpose. In this case, consider using generics to make clear how you want AbsType to be used without coupling closely to the client's code, like
public class AbsType3<C extends Class<?>> {
public boolean method3(T classType) {...}
}
Then you can restrict the types of classes to allow if needed by exchanging the <C extends Class<?>> type parameter for something else which may also be an interface, like
<C extends Class<Collection<?>>>.
Empty interfaces are somewhat like boolean flags for classes: Either a class implements the interface (true) or it doesn't (false). If at all, these marker interfaces should be used to convey an significant statement about how a class is meant to be (or not to be) used, see Serializable for example.

Why java interfaces can't contain static methods implementations?

I'm just curious, wouldn't it be more convinient to allow interfaces to contain implementations of static methods? Such methods could contain short commonly used(by this interface implementors) logic.
Because an interface describes what. It doesn't describe how.
If you really want to add (hide) some logic inside an interface, you may consider adding an inner class (Note: never do it, this just shows what is possible from a pure technical perspective):
public interface Person {
public String getFirstName();
public String getLastName();
public class Util {
public String getName(Person person) {
return person.getFirstName() + " " + person.getLastName();
}
}
}
If you use this, it "feels" a bit like having static method code in the interface:
String fullName = Person.Util.getName(this);
As I said - it's pure technically and I don't see any reason to actually do it. A static method can be located in any class, no need to add it to an interface.
An interface is a contract. It says what an implementing object will have (at minimum), but that's all. It says "this house will have a door, a window, and a chimney".
An abstract class is more like a prefab house. It's not complete (you have to add your own siding, for example) but it has parts already there (there is a space for the door, but the whole fireplace is already setup.
The problem with giving code in interfaces is multiple inheritance. Java doesn't allow it. You can have a class implement many interfaces, because interfaces only promise there will be a method with a given signature.
If interfaces held code, then you could implement 3 of them, each with a method body for myUsefulFunction(String thing)... and now you don't know which one gets called.
That's why abstract classes can have method bodys (because you can only extend one class), but interfaces can't (because you can implement multiple interfaces).
I agree that a static method doesn't make sense in an interface. But i don't understand why java allows static members in an interface. Seems a bit inconsistent.
It's the abstract class or regular class which should implement something. Interfaces are not supposed to have any implementations, but they contain the interface of communicating. So static methods are not allowed.
An interface is a special abstract class with all abstract methods.
You can feel free to create an abstract class of your own that contains (non-abstract) static methods, but then you can only inherit from one of them.
Better yet, create a separate helper class with your static methods.

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