Object Oriented Programming (OOP) is a style of programming that incorporates these 3 features: Encapsulation Polymorphism Class Interaction Class Interaction There are 3 types of class interaction. One is inheritance, which the main focus of this chapter. Another is composition, which we will look at briefly. The third is utility classes which is explained on the next slide. Utility Classes You have been working with Utility Classes for a while. These are classes which are not used to create objects, but still contain several useful methods. The Math class and the Expo class are both perfect examples of this. Inheritance Inheritance is the process of using features (both attributes and methods) from an existing class. The existing class is called the superclass and the new class, which inherits the superclass features, is called the subclass. superclass: Car subclasses: Truck, Limo & Racecar “Is-A” and “Has-A” The creation of new classes with the help of existing classes makes an important distinction between two approaches. An "is-a" relationship declares a new class as a special “new-and-improved” case of an existing class. In Geometry, a parallelogram "is-a" quadrilateral with special properties. A “has-a” relationship declares a new class composed of an existing class or classes. A line "has" points, a square "has" lines, and a cube "has" squares. A truck "is-a" car, but it "has-an" engine. Composition Composition occurs when the data attributes of one class are objects of another class. You do NOT say “A Car is-an Engine” or “A Car is 4 tires” but you DO say “A Car has-an Engine” & “A car has 4 tires.” class: Car Contained Objects: 1 Engine 4 Tires Inheritance vs. Composition In computer science an "is-a" relationship is called inheritance “A TireSwing is-a Swing”. and a "has-a" relationship is called composition. “A TireSwing has-a Tire.” // Java0901.java // This program presents a <Person> class and a <Student> class. // The main method calls the <showAge> method with a <Student> object. // This program will not compile. Java cannot find the <showAge> method. public class Java0901 { public static void main(String args[]) { System.out.println("\nJAVA0901\n"); Student tom = new Student(); tom.showAge(); tom.showGrade(); System.out.println(); } } class Person { private int age; public void showAge() { System.out.println("Person's Age is unknown right now"); } } class Student { private int grade; public void showGrade() { System.out.println("Student's Grade is unknown right now"); } } // Java0902.java // This program demonstrates fundamental inheritance with <extends>. // The <Student> is declared as a subclass of the <Person> superclass. // Now the program compiles and executes correctly. public class Java0902 { public static void main(String args[]) { System.out.println("\nJAVA0902\n"); Student tom = new Student(); tom.showAge(); tom.showGrade(); System.out.println(); } } class Person { private int age; public void showAge() { System.out.println("Person's Age is unknown right now"); } } class Student extends Person { private int grade; public void showGrade() { System.out.println("Student's Grade is unknown right now"); } } // Java0903.java // This program adds constructors to the <Person> &<Student> classes. Note how the <Person> // constructor is called, even though there does not appear to be a <Person> object instantiated. public class Java0903 { public static void main(String args[]) { System.out.println("\nJAVA0903\n"); Student tom = new Student(); System.out.println(); } } class Person { private int age; public Person() { System.out.println("Person Constructor"); age = 17; } } class Student extends Person { private int grade; public Student() { System.out.println("Student Constructor"); grade = 12; } } Inheritance and Constructors When an object of a subclass is instantiated, the constructor of the superclass is called first, followed by a call to the constructor of the subclass. // Java0904.java // This program shows that the subclass does not have access to the private data // of the superclass. This program will not compile. public class Java0904 { public static void main(String args[]) { System.out.println("\nJAVA0904\n"); Student tom = new Student(); tom.showData(); System.out.println(); } } class Person { private int age; public Person() { System.out.println("Person Constructor"); age = 17; } } class Student extends Person { private int grade; public Student() { System.out.println("Student Constructor"); grade = 12; } public void showData() { System.out.println("Student's Grade is System.out.println("Student's Age is } } " + grade); " + age ); // Java0905.java // This program changes private super class data access to "protected". // The Student class can now access data from the Person class. public class Java0905 { public static void main(String args[]) { System.out.println("\nJAVA0905\n"); Student tom = new Student(); tom.showData(); System.out.println(); } } class Person { protected int age; public Person() { System.out.println("Person Constructor"); age = 17; } } class Student extends Person { private int grade; public Student() { System.out.println("Student Constructor"); grade = 12; } public void showData() { System.out.println("Student's Grade is System.out.println("Student's Age is } } " + grade); " + age ); public, private & protected Attributes & methods declared public can be accessed by methods declared both outside and inside the class. Attributes & methods declared private can only be accessed by methods declared inside the class. Attributes & methods declared protected can be accessed by methods declared inside the class or subclass. // Java0906.java This program demonstrates inheritance at three levels. public class Java0906 { public static void main(String args[]) { System.out.println("\nJAVA0906\n"); Cat cat = new Cat("Tiger"); System.out.println(); System.out.println("Animal type: " + cat.getType()); System.out.println("Animal weight: " + cat.getWeight()); System.out.println("Animal age: " + cat.getAge()); System.out.println(); } } class Animal class Mammal extends Animal { public int weight; public Mammal() { weight = 500; System.out.println( "Mammal Constructor Called"); } public int getWeight() { return weight; } } class Cat extends Mammal { { protected int age; public Animal() { System.out.println("Animal Constructor Called"); age = 15; } public int getAge() { return age; } } private String type; public Cat() { type = "Tiger"; System.out.println( "Cat Constructor Called"); } public String getType() { return type; } } Multi-Level Inheritance & Multiple Inheritance The previous program showed an example of Multi-Level Inheritance. Multiple Inheritance is something different. It occurs when one subclass inherits from two or more superclasses. This feature is available in C++. It is NOT available in Java. Multi-Level Inheritance Animal Multiple Inheritance Reptile Extinct Mammal Dinosaur Dog Terrier Inheritance Demonstrated with GridWorld-1 In GridWorld, if you click on an Actor object, you will see all of the methods available from the Actor class. Inheritance Demonstrated with GridWorld-2 If you click on a Bug object, you will see all of the Bug methods. You will also see all of the methods Bug inherits from Actor. Inheritance Demonstrated with GridWorld-3 Here, Multi-Level Inheritance is demonstrated because an OctagonBug (Spider) inherits from a Bug, and a Bug inherits from an Actor. // Java0907.java The Fish class, Stage #1 // The Fish1 class can only draw a fish at a fixed starting location. import java.awt.*; import java.applet.*; public class Java0907 extends Applet { public void paint(Graphics g) { Fish1 f1 = new Fish1(); f1.drawFish(g); } } class Fish1 { protected int x; // center X coordinate of the fish protected int y; // center Y coordinate of the fish protected int direction; // one of 4 directions fish is facing: 0-N, 90-E, 180-S, 270-W public Fish1() { x = 500; y = 300; direction = 0; } public void drawFish(Graphics g) { Expo.setColor(g,Expo.black); switch (direction) { case 0: Expo.fillOval(g,x,y,15,30); Expo.fillPolygon(g,x,y+30,x-15,y+40,x+15,y+40); break; case 90: Expo.fillOval(g,x,y,30,15); Expo.fillPolygon(g,x-30,y,x-40,y-15,x-40,y+15); break; case 180: Expo.fillOval(g,x,y,15,30); Expo.fillPolygon(g,x,y-30,x-15,y-40,x+15,y-40); break; case 270: Expo.fillOval(g,x,y,30,15); Expo.fillPolygon(g,x+30,y,x+40,y-15,x+40,y+15); break; default: System.out.println("ERROR!!! Direction must be 0,90,180,270"); } } } // Java0908.java The Fish class, Stage #2 // The Fish2 class inherits the drawFish method. // Additionally, it adds a method to erase the fish and turn the fish. import java.awt.*; import java.applet.*; public class Java0908 extends Applet { public void paint(Graphics g) { Fish2 f2 = new Fish2(); f2.drawFish(g); f2.turnFish(g); f2.turnFish(g); f2.turnFish(g); f2.turnFish(g); } } class Fish2 extends Fish1 { public void turnFish(Graphics g) { Expo.delay(1000); eraseFish(g); direction += 90; if (direction == 360) direction = 0; drawFish(g); } public void eraseFish(Graphics g) { Expo.setColor(g,Expo.white); switch (direction) { case 0: Expo.fillOval(g,x,y,15,30); Expo.fillPolygon(g,x,y+30,x-15,y+40,x+15,y+40); break; case 90: Expo.fillOval(g,x,y,30,15); Expo.fillPolygon(g,x-30,y,x-40,y-15,x-40,y+15); break; case 180: Expo.fillOval(g,x,y,15,30); Expo.fillPolygon(g,x,y-30,x-15,y-40,x+15,y-40); break; case 270: Expo.fillOval(g,x,y,30,15); Expo.fillPolygon(g,x+30,y,x+40,y-15,x+40,y+15); break; default: System.out.println("ERROR!!! Direction must be 0,90,180,270"); } } } // Java0909.java The Fish class, Stage #3 // The Fish3 class adds method moveFish, which moves the Fish object to a specified coordinate. import java.awt.*; import java.applet.*; public class Java0909 extends Applet { public void paint(Graphics g) { Fish3 f3 = new Fish3(); f3.drawFish(g); f3.moveFish(g,800,200); f3.turnFish(g); f3.moveFish(g,300,500); f3.turnFish(g); } } class Fish3 extends Fish2 { public void moveFish(Graphics g, int newX, int newY) { Expo.delay(1000); eraseFish(g); x = newX; y = newY; drawFish(g); } } // Java0910.java The Fish class, Stage #4 // The Fish4 class redefines the moveFish method. Fish objects will now move without erasing themselves. // Additionally, the Fish4 class adds a constructor, which draws a Fish object at a specified starting location. import java.awt.*; import java.applet.*; public class Java0910 extends Applet { public void paint(Graphics g) { int xPos = 100; int yPos = 100; int direction = 90; Fish4 f4 = new Fish4(xPos,yPos,direction); for (int k = 1; k <= 8; k++) { xPos += 80; f4.moveFish(g,xPos,yPos); } } } class Fish4 extends Fish3 { public Fish4(Graphics g, int xPos, int yPos, int dir) public void moveFish(Graphics g, int newX, int newY) { { x = xPos; y = yPos; direction = dir; drawFish(g); } } Expo.delay(1000); x = newX; y = newY; drawFish(g); } Square Fish Challenge Change Program Java0910.java so that it displays a “square” of fish. To make the square fit, change the number of fish in the for loop from 8 to 6. NOTE: This will be similar to the GridWorld labs. for (int k = 1; k <= 6 ; k++) { xPos += 80; f4.moveFish(g,xPos,yPos); }