Abstract classes do pretty much what classes do but with a bit of restriction.
Example 1 (abstract classes)
Take the following code:
An abstract class Car.java
package basics; public abstract class Car { // constructor public Car(){ System.out.print("print"); } }
StartingPoint.java
package basics; public class StartingPoint { public static void main(String[] args) { // the following line Car c= new Car(); // throws an error as we are cannot instatiate an abstract class } }
The above code throws an error as we cannot instantiate an abstract class.
Example 2 (abstract classes)
… however, if we make a subclass or Car (Toyota.java) below, Toyota will inherit the stuff inside the Car class making the methods within the Car class accessible again. I.e. we can instantiate an object for the Toyota call (which inherits everything from the Car class). Another way of saying this is that abstract classes can be used as a superclass to a subclass.
StartingPoint.java
package basics; public class StartingPoint { public static void main(String[] args) { // the following line // Car c= new Car(); // throws an error as we are cannot instatiate an abstract class Toyota t = new Toyota(); } }
Car.class (the abstract class)
package basics; public abstract class Car { // constructor public Car(){ System.out.print("print"); } }
Toyota.java
package basics; // the abtract class Car becomes the superclass // and class Toyota becomes the subclass public class Toyota extends Car{ }
Output:
Note: we can also access methods in the Car class via the Toyota class (Toyota extends Car)
Example 3 (abstract methods)
We can also set up abstract methods with the abstract Car class. If we do this, we then have to @override ALL these methods in the subclass.
In the car class, the abstract method is saying saying, if anyone extends me, they’re going to have to use my methods.
StartingPoint.java
package basics; public class StartingPoint { public static void main(String[] args) { // the following line // Car c= new Car(); // throws an error as we are cannot instatiate an abstract class Toyota t = new Toyota(); System.out.println(t.mpg(60,2)); t.tireSize(1979, "BMW"); } }
Car.java
package basics; public abstract class Car { // constructor public Car(){ System.out.println("print"); } public double mpg(double miles, double gallons){ return (miles/gallons); } // abstract methods CANNOT have a body // when we set up these two methods below, we will HAVE // to use them in the subclass that EXTENDS this class public abstract void carComputerSetup(); public abstract void tireSize(int year, String model); }
Toyota.java
package basics; // the abtract class Car becomes the superclass // and class Toyota becomes the subclass public class Toyota extends Car{ @Override public void carComputerSetup() { System.out.println("setup the computer"); } @Override public void tireSize(int year, String model) { System.out.println("Tire... Model "+model+ "year "+year+" you want small tire"); } }
Outputs:
print
30.0
Tire… Model BMWyear 1979 you want small tire
Example 4 (polymorphism)
StartingPoint.java
package basics; public class StartingPoint { public static void main(String[] args) { // the following line // Car c= new Car(); // throws an error as we are cannot instatiate an abstract class Toyota t = new Toyota(); t.speak(); // POLYMORPHISM // the following can be done because each of the // individual cars EXTENDS the car class // they are the subclasses of car Car c1,c2,c3; c1 = new Toyota(); c2 = new Honda(); c3 = new Ford(); // POLYMORPHISM allows the car object to know to // use the speak() method in the subclass // Because c3.speak() method doesn't exist in the // Ford class, it uses the superclass (the Car car) speak() method c1.speak(); c2.speak(); c3.speak(); } }
Car.java
package basics; public abstract class Car { // constructor public Car(){ //System.out.println("print"); } public double mpg(double miles, double gallons){ return (miles/gallons); } // abstract methods CANNOT have a body public abstract void carComputerSetup(); public abstract void tireSize(int year, String model); public void speak(){ System.out.println("I am a car"); } }
Toyota.java
package basics; // the abtract class Car becomes the superclass // and class Toyota becomes the subclass public class Toyota extends Car{ @Override public void carComputerSetup() { System.out.println("setup the computer"); } @Override public void tireSize(int year, String model) { System.out.println("Tire... Model "+model+ "year "+year+" you want small tire"); } @Override public void speak(){ System.out.println("I am a Toyta"); } }
Honda.java
package basics; public class Honda extends Car{ @Override public void carComputerSetup() { // } @Override public void tireSize(int year, String model) { // } @Override public void speak(){ System.out.println("I am a Honda"); } }
Ford.java
package basics; public class Ford extends Car { @Override public void carComputerSetup() { // } @Override public void tireSize(int year, String model) { // } }
Outputs:
I am a Toyta
I am a Toyta
I am a Honda
I am a car
Example 5 (polymorphism)
Keeping all the other files the same but changing StartingPoint.java shows another interesting aspect of polymorphism.
StartingPoint.java
public class StartingPoint { public static void main(String[] args) { // the following line // Car c= new Car(); // throws an error as we are cannot instatiate an abstract class Toyota t = new Toyota(); t.speak(); test(t); } private static void test(Toyota t) { System.out.println("test"); } //private static void test(Car c) { // System.out.println("test"); //} }
Outputs:
I am a Toyta
test
Note the commented out code at the end
//private static void test(Car c) {
// System.out.println(“test”);
//}
Even though we call
test(t);
so passing the the Toyota object, because Toyota is a subclass of Car, we COULD pass in a Car object and get the same results.