/* Abstract Class By now you should understand the difference between classes and interfaces and what interfaces are used for. An *abstract class* is another structure that is somewhat in between a class and an interface. 1. It can contain method declarations without bodies, such as public abstract int f(); This is similar to what's found in an interface. 2. It can also contain full methods with both declaration and implementation: public String g() { return "hello"; } 3. Although it's possible to write a constructor in an abstract class, you cannot create an instance of an abstract class just as you cannot create an instance of an interface. An abstract class is incomplete. Only concrete (non-abstract) classes can have instances. The constructor of an abstract class is only called from the constructor of its subclasses, not from 'new'. 4. An abstract class can contain instance variables. 5. A class, abstract or not, can extend an abstract class. When a non-abstract (conrete) class extends an abstract class, it must provide implementations of all method declarations marked "abstract". Thus an abstract class has the characteristics of both a class and an interface. The following is considered a classic example of object oriented programming using an abstract class. */ abstract class shape implements Comparable { protected int x, y; // position of shape (instance variables) /* abstract methods are like declarations in an interface:*/ public abstract double area(); public abstract double circumference(); // classes that extend shape must implement these methods. // an abstract class can also contain regular methods: public double distanceto(shape other) { double dx = x-other.x, dy = y-other.y; return Math.sqrt(dx*dx + dy*dy); } public int compareTo(shape other) { // compare objects based on area. double a = this.area(), b = other.area(); if (a==b) return 0; else if (a0) S[3] = new circle(5,5,5); else S[3] = new square(4,4,4); //What's the 'type' of S[3]? System.out.println(S[0].distanceto(S[2])); System.out.println(S[1].compareTo(S[0])); double totalarea = 0; for(shape s:S) totalarea += s.area(); // which area() is being called? System.out.println( totalarea ); // System.out.println(S[0].radius) // compiler error? why? // The above line will not compile because to the compiler, // the type of S[0] is "shape", which does not have a radius. // The compiler is not aware of the dynamic/runtime type of // S[0], which is a circle. System.out.println("S[0] has radius" + ((circle)S[0]).radius); // OK System.out.println("S[1] has radius" + ((circle)S[1]).radius); // ??? // the above line will compile but will result in a runtime exception. }//main } /* ***************** Quiz: What's wrong with the following program: abstract class A { protected int x; public A(int x0) {x = x0; } public abstract int f(int y); public int g() { return x + f(1); } public void h() {} }//A class B extends A { public B(int x0) { super(x0); } public int f(int y) { return y*x; } } public class goodquestion { public static void main() { A n = new B(1); System.out.println(n.f(3)); System.out.println(n.g()); A m = new A(2); m.h(); } } ANSWER: The only thing wrong is at the end of main: A m = new A(2); tries to create an instance of an abstract class. Of course m.h() also can't be called if m can't be created. */ /* ===== The Foundations of OOP ===== There are many different versions of the shapes example, some using an interface instead of an abstract class. It's considered a classic example of object oriented programming. Advanced OOP requires three key components: 1. Dynamic type information 2. Dynamic memory allocation 3. Dynamic dispatch "Object Oriented Abstraction" requires a separation between the abstract view of objects from their concrete view. The abstract view is usually a general superclass, an abstract superclass, or an interface. Referring to the shapes example, the abstract view of objects is that they're "shapes" and the concrete view is that they're circles, rectangles, squares, etc. For example, we may wish to place different shapes into a data structure. In defining the data structure we take the abstract view of shapes, but when placing individual shapes into the structure we take the concrete view. shape[] S = new shape[3]; // array of abstract shapes S[0] = new circle(radius); // a concrete shape S[1] = new rectangle(width,height); if (..) S[2] = new circle(..) else S[2] = new rectangle(..,..); S[1] = new square(..); // a shape can even change shape double totalarea = 0; for(int i=0;i