Abstraction is the concept of hiding away the details. It can basically be summed up with this phrase: I don't care how it happens, just get it done.
There are many ways to abstract away the details. The main way is through methods/functions, or objects. Here's an example:
Let's say you want to test if a number is prime or not. How would you do this? You could execute this code:
int number = ...; // number you want to test if prime boolean isPrime = true; if (number < 2 || (number % 2 == 0 && number != 2)) { isPrime = false; } for (int i = 3; i < number && isPrime; i++) { if (number % i == 0) { isPrime = false; } }
But do you really want to put that code everywhere you need to test if a number is prime? No. Instead, you want to abstract away the details in a method, let's say called isPrime.
int number = ...; // number you want to test if prime boolean isPrimeNumber = isPrime(number);
For us, it isn't necessary for us to know what the isPrime method is doing. All we need to know are this:
1. What is the name of the method? isPrime
2. What are it's inputs? an integer number you want to test if it's prime.
3. What is it's output? true if the number is prime, false otherwise. Numbers <= 1 are not prime
So, now you may be asking how do you know if isPrime works correctly, or what if it's run-time is horrible?
The answer to these is that in the perspective of the caller IT DOESN"T MATTER. When you want to mess around with the isPrime details, you can scroll over to the isPrime method and edit it's details INDEPENDENT of everything else.
This makes development and debugging much easier because you're creating an idea that people can work with. The first bit of code that calculated if a number was prime would be pretty hard to decipher quickly. If it's not, there will be ideas that you want to abstract away that will be difficult to understand. An example would be to calculate the next move a computer should make in a game of chess. I won't go into the details here (haha, that's suppose to be a pun) but wouldn't it be so much nicer if the area of code that manages turns had this code:
while (board.stillPlayable()) { numberboard.moveComputersPiece(); board.getUsersMove(); }
Abstract classes
I decided this was important enough that it should go in its own sub-category under abstract. Abstract classes are those that are not completely defined on their own, but are defined for any concrete (non-abstract) inheriting classes. An example is if we had a Shape class. What is the area of a shape (aka, how do we compute this)? It's inherently undefined for a Shape, but if we inherit a class from shape, say Circle, it MUST define what the area is (unless, of course you declare that abstract as well, but that's just silly).
To make classes abstract, you simply need to put the abstract keyword in the class declaration. To declare methods abstract, you do the same thing for the methods you want to be abstract. Fields can never be abstract (can you see why?).
Abstract classes in most senses operate just like their concrete counterparts: You can have public/protected/private fields and methods, they can be static or instanced, and they can also be declared final (note: abstract methods can NOT be private or final). A special thing about abstract classes, though, is that they can NOT be instantiated directly. The reason is the class by itself is not completely implemented. What if you tried to find the area of a Shape? You will fail. The only way to use abstract classes is via Polymorphism (this is now a link, click on it!).
*Note: If a class has even 1 abstract method, it must have the abstract keyword in the class declaration.
public abstract class Shape { public int x,y; public Shape(int x, int y) { this.x = x; this.y = y; } public abstract double Area(); }
So why is this above Shape class perfectly legal? I thought I said you couldn't instantiate abstract classes, yet this one has a constructor! The answer is that even though abstract classes can't be instantiated on their own, they are still a part of any inheriting classes. Thus, constructors should be and are used by inheriting classes to set up the inherited portion of the child class. For more info on this, see the Inheritance section (this is a link).
Q&A time:
Here are some simple questions regarding abstraction and abstract classes. If you can answer all these questions by yourself, you probably understand the concept of abstraction.
1. How do you declare a class abstract?
2. What is the difference between an abstract class and a non-abstract (concrete) class?
3. Why can't you instantiate an abstract class?
4. Can static methods be abstract?
5. What is the simplest way to abstract away details?
6. What must you provide in order to gain an entire concept that was abstracted away in a method without going into implementation details?
Here are the answers. I tried to conceal them some-what, i need to find a better way to do this... anyways, if you're having trouble reading them, just highlight them with your cursor.
1. Put the abstract keyword in the class declaration
2. Abstract classes can have methods that aren't implemented yet (abstract methods). Concrete methods must not have any abstract methods, including those it may inherit from parent classes and those it implements from interfaces.
3. It is not completely defined. Think of what would happen if you tried calling an abstract method that hasn't been implemented yet:
What should the computer do? To prevent this quandary, Java won't let abstract classes be instantiated, even if they contain no abstract methods (declaring a class abstract without any abstract methods is then of course, silly)
4. No. The reason is you call static methods from the class itself, so you could theoretically encounter the same problem as above: trying to run a method that hasn't been implemented yet.
5. With methods and classes/objects.
6. Name, parameters, and expected output. Note: how the method arrives to the expected output is incorrect (that's what the abstraction gets rid of)
abstract class SomeClass{}
2. Abstract classes can have methods that aren't implemented yet (abstract methods). Concrete methods must not have any abstract methods, including those it may inherit from parent classes and those it implements from interfaces.
3. It is not completely defined. Think of what would happen if you tried calling an abstract method that hasn't been implemented yet:
abstract class someClass { public abstract void doIt(); }
What should the computer do? To prevent this quandary, Java won't let abstract classes be instantiated, even if they contain no abstract methods (declaring a class abstract without any abstract methods is then of course, silly)
4. No. The reason is you call static methods from the class itself, so you could theoretically encounter the same problem as above: trying to run a method that hasn't been implemented yet.
5. With methods and classes/objects.
6. Name, parameters, and expected output. Note: how the method arrives to the expected output is incorrect (that's what the abstraction gets rid of)