Có hai cách để sử dụng lại các lớp hiện có, đó là thành phần và kế thừa . Với thành phần (còn gọi là tổng hợp ), bạn định nghĩa một lớp mới, bao gồm các lớp hiện có. Với tính kế thừa , bạn lấy được một lớp mới dựa trên một lớp hiện có, với các sửa đổi hoặc phần mở rộng.
1. Composition - Thành Phần
Chúng ta sẽ bắt đầu với việc sử dụng lại các lớp thông qua thành phần - với các ví dụ sau:
1.1 Composition EG. 1: The Author and Book Classes
Author Class (Author.java)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | /** * The Author class model a book's author. */ public class Author { // The private instance variables private String name; private String email; private char gender; // 'm' or 'f' /** Constructs a Author instance with the given inputs */ public Author(String name, String email, char gender) { this.name = name; this.email = email; this.gender = gender; } // The public getters and setters for the private instance variables. // No setter for name and gender as they are not designed to be changed. /** Returns the name */ public String getName() { return name; } /** Returns the gender */ public char getGender() { return gender; } /** Returns the email */ public String getEmail() { return email; } /** Sets the email */ public void setEmail(String email) { this.email = email; } /** Returns a self-descriptive String */ public String toString() { return name + " (" + gender + ") at " + email; } } |
TestAuthor.java
/** * A test driver for the Author class. */ public class TestAuthor { public static void main(String[] args) { // Test constructor and toString() Author ahTeck = new Author("Tan Ah Teck", "teck@nowhere.com", 'm'); System.out.println(ahTeck); // toString() //Tan Ah Teck (m) at teck@nowhere.com // Test Setters and Getters ahTeck.setEmail("teck@somewhere.com"); System.out.println(ahTeck); // toString() //Tan Ah Teck (m) at teck@somewhere.com System.out.println("name is: " + ahTeck.getName()); //name is: Tan Ah Teck System.out.println("gender is: " + ahTeck.getGender()); //gender is: m System.out.println("email is: " + ahTeck.getEmail()); //email is: teck@somewhere.com } }
Một cuốn sách Book được viết bởi một Author - Sử dụng "Object" Member Variable (biến thành phần là một đối tượng)
Book Class (Book.java)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 | /** * The Book class models a book with one (and only one) author. */ public class Book { // The private instance variables private String name; private Author author; private double price; private int qty; /** Constructs a Book instance with the given author */ public Book(String name, Author author, double price, int qty) { this.name = name; this.author = author; this.price = price; this.qty = qty; } // Getters and Setters /** Returns the name of this book */ public String getName() { return name; } /** Return the Author instance of this book */ public Author getAuthor() { return author; // return member author, which is an instance of the class Author } /** Returns the price */ public double getPrice() { return price; } /** Sets the price */ public void setPrice(double price) { this.price = price; } /** Returns the quantity */ public int getQty() { return qty; } /** Sets the quantity */ public void setQty(int qty) { this.qty = qty; } /** Returns a self-descriptive String */ public String toString() { return "'" + name + "' by " + author; // author.toString() } } |
Book Class (TestBook.java)
/** * A test driver program for the Book class. */ public class TestBook { public static void main(String[] args) { // We need an Author instance to create a Book instance Author ahTeck = new Author("Tan Ah Teck", "ahTeck@somewhere.com", 'm'); System.out.println(ahTeck); // Author's toString() //Tan Ah Teck (m) at ahTeck@somewhere.com // Test Book's constructor and toString() Book dummyBook = new Book("Java for dummies", ahTeck, 9.99, 99); System.out.println(dummyBook); // Book's toString() //'Java for dummies' by Tan Ah Teck (m) at ahTeck@somewhere.com // Test Setters and Getters dummyBook.setPrice(8.88); dummyBook.setQty(88); System.out.println("name is: " + dummyBook.getName()); //name is: Java for dummies System.out.println("price is: " + dummyBook.getPrice()); //price is: 8.88 System.out.println("qty is: " + dummyBook.getQty()); //qty is: 88 System.out.println("author is: " + dummyBook.getAuthor()); // invoke Author's toString() //author is: Tan Ah Teck (m) at ahTeck@somewhere.com System.out.println("author's name is: " + dummyBook.getAuthor().getName()); //author's name is: Tan Ah Teck System.out.println("author's email is: " + dummyBook.getAuthor().getEmail()); //author's email is: ahTeck@somewhere.com System.out.println("author's gender is: " + dummyBook.getAuthor().getGender()); //author's gender is: m // Using an anonymous Author instance to create a Book instance Book moreDummyBook = new Book("Java for more dummies", new Author("Peter Lee", "peter@nowhere.com", 'm'), // an anonymous Author's instance 19.99, 8); System.out.println(moreDummyBook); // Book's toString() //'Java for more dummies' by Peter Lee (m) at peter@nowhere.com } }
Lưu ý: Trong ví dụ này, tôi đã sử dụng "
name
" cho Book
lớp thay vì " title
" để minh họa rằng bạn có thể có một biến name
trong cả lớp Author
và Book
lớp, nhưng chúng khác biệt.1.2 Composition EG. 2: Point và Line Classes
Line Class via Composition (Line.java)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 | /** * A Line composes of two Points - a begin "Point" and an end "Point". * We reuse the Point class via composition. */ public class Line { // The private instance variables Point begin, end; // instances of the "Point" class /** Constructs a Line instance given 2 points at (x1, y1) and (x2, y2) */ public Line(int x1, int y1, int x2, int y2) { begin = new Point(x1, y1); // Construct the instances declared end = new Point(x2, y2); } /** Construct a Line instance given 2 Point instances */ public Line(Point begin, Point end) { this.begin = begin; // The caller had constructed the instances this.end = end; } // The public getter and setter for the private instance variables public Point getBegin() { return begin; } public Point getEnd() { return end; } public void setBegin(Point begin) { this.begin = begin; } public void setEnd(Point end) { this.end = end; } public int getBeginX() { return begin.getX(); // Point's getX() } public void setBeginX(int x) { begin.setX(x); // Point's setX() } public int getBeginY() { return begin.getY(); // Point's getY() } public void setBeginY(int y) { begin.setY(y); // Point's setY() } public int[] getBeginXY() { return begin.getXY(); // Point's getXY() } public void setBeginXY(int x, int y) { begin.setXY(x, y); // Point's setXY() } public int getEndX() { return end.getX(); // Point's getX() } public void setEndX(int x) { end.setX(x); // Point's setX() } public int getEndY() { return end.getY(); // Point's getY() } public void setEndY(int y) { end.setY(y); // Point's setY() } public int[] getEndXY() { return end.getXY(); // Point's getXY() } public void setEndXY(int x, int y) { end.setXY(x, y); // Point's setXY() } /** Returns a self-descriptive String */ public String toString() { return "Line[begin=" + begin + ",end=" + end + "]"; // Invoke begin.toString() and end.toString() } /** Returns the length of this line */ public double getLength() { return begin.distance(end); // use Point's distance() method } } |
TestLine.java
import java.util.Arrays; /** * A Test Driver for the Line class. */ public class TestLine { public static void main(String[] args) { // Test constructor and toString() Line l1 = new Line(1, 2, 3, 4); System.out.println(l1); // Line's toString() //Line[begin=(1,2),end=(3,4)] Line l2 = new Line(new Point(5,6), new Point(7,8)); // anonymous Point's instances System.out.println(l2); // Line's toString() //Line[begin=(5,6),end=(7,8)] // Test Setters and Getters l1.setBegin(new Point(11, 12)); l1.setEnd(new Point(13, 14)); System.out.println(l1); // Line's toString() //Line[begin=(11,12),end=(13,14)] System.out.println("begin is: " + l1.getBegin()); // Point's toString() //begin is: (11,12) System.out.println("end is: " + l1.getEnd()); // Point's toString() //end is: (13,14) l1.setBeginX(21); l1.setBeginY(22); l1.setEndX(23); l1.setEndY(24); System.out.println(l1); // Line's toString() //Line[begin=(21,22),end=(23,24)] System.out.println("begin's x is: " + l1.getBeginX()); //begin's x is: 21 System.out.println("begin's y is: " + l1.getBeginY()); //begin's y is: 22 System.out.println("end's x is: " + l1.getEndX()); //end's x is: 23 System.out.println("end's y is: " + l1.getEndY()); //end's y is: 24 l1.setBeginXY(31, 32); l1.setEndXY(33, 34); System.out.println(l1); // Line's toString() //Line[begin=(31,32),end=(33,34)] System.out.println("begin's x and y are: " + Arrays.toString(l1.getBeginXY())); //begin's x and y are: [31, 32] System.out.println("end's x and y are: " + Arrays.toString(l1.getEndXY())); //end's x and y are: [33, 34] // Test getLength() System.out.printf("length is: %.2f%n", l1.getLength()); //length is: 2.83 } }
Exercise: Try writing these more complex methods for the
Line
class:// Return the gradient of this line in radian (use Math.atan2(y, x)). public double getGradient() // Return the distance from this line to the given point. public double distance(int x, int y) public double distance(Point p) // Return true if this line intersects the given line. public boolen intersects(Line another)
1.3 Composition EG. 3: Point và Circle Classes
Circle class (Circle.java)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 | /** * The Circle class composes a "Point" instance as its center and a radius. * We reuse the "Point" class via composition. */ public class Circle { // The private member variables private Point center; // Declare an instance of the "Point" class private double radius; // Constructors /** Constructs a Circle instance with the default values */ public Circle() { this.center = new Point(); // Construct a Point at (0,0) this.radius = 1.0; } /** Constructs a Circle instance with the center at (xCenter, yCenter) and radius */ public Circle(int xCenter, int yCenter, double radius) { center = new Point(xCenter, yCenter); // Construct a Point at (xCenter,yCenter) this.radius = radius; } /** Constructs a Circle instance with the given Point instance as center and radius */ public Circle(Point center, double radius) { this.center = center; // The caller had constructed a Point instance this.radius = radius; } // Getters and Setters public double getRadius() { return this.radius; } public void setRadius(double radius) { this.radius = radius; } public Point getCenter() { return this.center; // return a Point instance } public void setCenter(Point center) { this.center = center; } public int getCenterX() { return center.getX(); // Point's getX() } public void setCenterX(int x) { center.setX(x); // Point's setX() } public int getCenterY() { return center.getY(); // Point's getY() } public void setCenterY(int y) { center.setY(y); // Point's setY() } public int[] getCenterXY() { return center.getXY(); // Point's getXY() } public void setCenterXY(int x, int y) { center.setXY(x, y); // Point's setXY() } /** Returns a self-descriptive String */ public String toString() { return "Circle[center=" + center + ",radius=" + radius + "]"; // invoke center.toString() } /** Returns the area of this circle */ public double getArea() { return Math.PI * radius * radius; } /** Returns the circumference of this circle */ public double getCircumference() { return 2.0 * Math.PI * radius; } /** Returns the distance from the center of this circle to the center of the given Circle instance called another */ public double distance(Circle another) { return center.distance(another.center); // Use distance() of the Point class } } |
TestCircle.java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | /** * A test driver for the Circle class. */ public class TestCircle { public static void main(String[] args) { // Test Constructors and toString() Circle c1 = new Circle(); System.out.println(c1); // Circle's toString() Circle c2 = new Circle(1, 2, 3.3); System.out.println(c2); // Circle's toString() Circle c3 = new Circle(new Point(4, 5), 6.6); // an anonymous Point instance System.out.println(c3); // Circle's toString() // Test Setters and Getters c1.setCenter(new Point(11, 12)); c1.setRadius(13.3); System.out.println(c1); // Circle's toString() System.out.println("center is: " + c1.getCenter()); // Point's toString() System.out.println("radius is: " + c1.getRadius()); c1.setCenterX(21); c1.setCenterY(22); System.out.println(c1); // Circle's toString() System.out.println("center's x is: " + c1.getCenterX()); System.out.println("center's y is: " + c1.getCenterY()); c1.setCenterXY(31, 32); System.out.println(c1); // Circle's toString() System.out.println("center's x is: " + c1.getCenterXY()[0]); System.out.println("center's y is: " + c1.getCenterXY()[1]); // Test getArea() and getCircumference() System.out.printf("area is: %.2f%n", c1.getArea()); System.out.printf("circumference is: %.2f%n", c1.getCircumference()); // Test distance() System.out.printf("distance is: %.2f%n", c1.distance(c2)); System.out.printf("distance is: %.2f%n", c2.distance(c1)); } } |
Đăng nhận xét