En este ejercicio se va a escribir un programa en el que varias clases, que están relacionadas mediante la herencia se crean y usan. Primero se crea una clase Person. Después se crean subclases de la clase Person, clase Student y clase Teacher. También se crea una subclase de la clase Student, que se llama clase InternationalStudent
class.
1. Crear un nuevo proyecto NetBeans
package mypeopleexample; public class Person { private String name; private String address; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } } |
package mypeopleexample; public class Student extends Person { private String school; private double grade; public String getSchool() { return school; } public void setSchool(String school) { this.school = school; } public double getGrade() { return grade; } public void setGrade(double grade) { this.grade = grade; } } |
package mypeopleexample; public class InternationalStudent extends Student { private String country; public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } } |
package mypeopleexample; public class Teacher extends Person { private String subject; public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } } |
package mypeopleexample; public class Main { public static void main(String[] args) { // Create object instances and invoke methods. // Note that you can use methods defined in a parent // class for object instances of the child class. Person person1 = new Person(); person1.setName("Tom Jones"); Student student1 = new Student(); student1.setName("CCR"); student1.setSchool("Lexington High"); InternationalStudent internationalStudent1 = new InternationalStudent(); internationalStudent1.setName("Bill Clinton"); internationalStudent1.setSchool("Lexington High"); internationalStudent1.setCountry("Korea"); Teacher teacher1 = new Teacher(); teacher1.setName("Beatles"); teacher1.setSubject("History"); // Display name of object instances using the getName() method // defined in the Person class. System.out.println("Displaying names of all object instances..."); System.out.println(" person1.getName() = " + person1.getName()); System.out.println(" student1.getName() = " + student1.getName()); System.out.println(" internationalStudent1.getName() = " + internationalStudent1.getName()); System.out.println(" teacher1.getName() = " + teacher1.getName()); } } |
Displaying names of all object
instances... person1.getName() = Tom Jones student1.getName() = CCR internationalStudent1.getName() = Bill Clinton teacher1.getName() = Beatles |
Volver al inicio del ejercicio
package mypeopleexample; public class Main { public static void main(String[] args) { // Create object instances and invoke methods. // Note that you can use methods defined in a parent // class for object instances of the child class. Person person1 = new Person(); person1.setName("Tom Jones"); Student student1 = new Student(); student1.setName("CCR"); student1.setSchool("Lexington High"); InternationalStudent internationalStudent1 = new InternationalStudent(); internationalStudent1.setName("Bill Clinton"); internationalStudent1.setSchool("Lexington High"); internationalStudent1.setCountry("Korea"); Teacher teacher1 = new Teacher(); teacher1.setName("Beatles"); teacher1.setSubject("History"); // Display name of object instances using the getName() method // defined in the Person class. System.out.println("Displaying names of all object instances..."); System.out.println(" person1.getName() = " + person1.getName()); System.out.println(" student1.getName() = " + student1.getName()); System.out.println(" internationalStudent1.getName() = " + internationalStudent1.getName()); System.out.println(" teacher1.getName() = " + teacher1.getName()); // Display the class hierarchy of the InternationalStudent // class through getSuperclass() method of Class class. Class class1 = internationalStudent1.getClass(); System.out.println("Displaying class hierarchy of InternationalStudent Class..."); while (class1.getSuperclass() != null){ String child = class1.getName(); String parent = class1.getSuperclass().getName(); System.out.println(" " + child + " class is a child class of " + parent); class1 = class1.getSuperclass(); } } } |
Displaying names of all object
instances... person1.getName() = Tom Jones student1.getName() = CCR internationalStudent1.getName() = Bill Clinton teacher1.getName() = Beatles Displaying class hierarchy of InternationalStudent Class... mypeopleexample.InternationalStudent class is a child class of mypeopleexample.Student mypeopleexample.Student class is a child class of mypeopleexample.Person mypeopleexample.Person class is a child class of java.lang.Object |
En este ejercicio se ha visto la creación de objetos que están relacionados a través de la herencia.
Volver al inicio
En este ejercicio, se experimenta con el concepto de la llamada encadenada de constructor y cómo usar el método super() y la referencia super.
package mypeopleexample; public class Person { public Person() { System.out.println("Person: constructor is called"); } private String name; private String address; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } } |
Código-2.10: Person.java
2. Modificar Student.java como se muestra en Código-2.11. El cambio consiste en añadir una sentencia de impresión dentro del constructor. El fragmento de código que se require añadir se muestra en azul.
package mypeopleexample; public class Student extends Person { public Student() { System.out.println("Student: constructor is called"); } private String school; private double grade; public String getSchool() { return school; } public void setSchool(String school) { this.school = school; } public double getGrade() { return grade; } public void setGrade(double grade) { this.grade = grade; } } |
package mypeopleexample; public class InternationalStudent extends Student { public InternationalStudent() { System.out.println("InternationalStudent: constructor is called"); } private String country; public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } } |
package mypeopleexample; public class Teacher extends Person { public Teacher() { System.out.println("Teacher: constructor is called"); } private String subject; public String getSubject() { return subject; } public void setSubject(String subject) { this.subject = subject; } } |
package mypeopleexample; public class Main { public static void main(String[] args) { // Create an object instance of // InternationalStudent class. System.out.println("---- About to create an object instance of InternationalStudent class..."); InternationalStudent internationalStudent1 = new InternationalStudent(); // Create an object instance of // Teacher class. System.out.println("---- About to create an object instance of Teacher class..."); Teacher teacher1 = new Teacher(); } } |
---- About to create an object instance of
InternationalStudent class... Person: constructor is called Student: constructor is called InternationalStudent: constructor is called ---- About to create an object instance of Teacher class... Person: constructor is called Teacher: constructor is called |
package mypeopleexample; public class Person { public Person() { System.out.println("Person: constructor is called"); } public Person(String name) { this.name = name; System.out.println("Person: constructor 2 is called"); } private String name; private String address; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } } |
package mypeopleexample; public class Student extends Person { public Student() { System.out.println("Student: constructor is called"); } public Student(String name, String school, double grade) { super(name); this.school = school; this.grade = grade; System.out.println("Student: constructor 2 is called"); } private String school; private double grade; public String getSchool() { return school; } public void setSchool(String school) { this.school = school; } public double getGrade() { return grade; } public void setGrade(double grade) { this.grade = grade; } } |
package mypeopleexample; public class InternationalStudent extends Student { public InternationalStudent() { System.out.println("InternationalStudent: constructor is called"); } public InternationalStudent(String name, String school, double grade, String country) { super(name, school, grade); this.country = country; System.out.println("InternationalStudent: constructor 2 is called"); } private String country; public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } } |
package mypeopleexample; public class Main { public static void main(String[] args) { // Create an object instance of // InternationalStudent class. System.out.println("---- About to create an object instance of InternationalStudent class..."); InternationalStudent internationalStudent1 = new InternationalStudent("Sang Shin", // Name "1 Dreamland", // Address 4.5, // Grade "Korea"); // Country System.out.println("internationalStudent1.getName() = " + internationalStudent1.getName()); System.out.println("internationalStudent1.getAddress() = " + internationalStudent1.getAddress()); System.out.println("internationalStudent1.getGrade() = " + internationalStudent1.getGrade()); System.out.println("internationalStudent1.getCountry() = " + internationalStudent1.getCountry()); } } |
---- About to create an object instance of
InternationalStudent class... Person: constructor 2 is called Student: constructor 2 is called InternationalStudent: constructor 2 is called internationalStudent1.getName() = Sang Shin internationalStudent1.getAddress() = null internationalStudent1.getGrade() = 4.5 internationalStudent1.getCountry() = Korea |
package mypeopleexample; public class Person { public Person() { System.out.println("Person: constructor is called"); } public Person(String name) { this.name = name; System.out.println("Person: constructor 2 is called"); } protected String name; protected String address; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } } |
package mypeopleexample; public class Student extends Person { public Student() { System.out.println("Student: constructor is called"); } public Student(String name, String school, double grade) { super(name); this.school = school; this.grade = grade; System.out.println("Student: constructor 2 is called"); } protected String school; protected double grade; public String getSchool() { return school; } public void setSchool(String school) { this.school = school; } public double getGrade() { return grade; } public void setGrade(double grade) { this.grade = grade; } } |
package mypeopleexample; public class InternationalStudent extends Student { public InternationalStudent() { System.out.println("InternationalStudent: constructor is called"); } public InternationalStudent(String name, String school, double grade, String country) { super.name = name; super.school = school; super.grade = grade; this.country = country; System.out.println("InternationalStudent: constructor 2 is called"); } private String country; public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } } |
---- About to create an object instance of
InternationalStudent class... Person: contructor is called Student: contructor is called InternationalStudent: contructor 2 is called internationalStudent1.getName() = Sang Shin internationalStudent1.getAddress() = null internationalStudent1.getGrade() = 4.5 internationalStudent1.getCountry() = Korea |
En este ejercicio se ha visto cómo los constructores de clases relacionadas se encadenan cuando se crea una instancia de un objeto. También se ha visto cómo usar el método super() para invocar un constructor de la clase padre.
Este ejercicio muestra el concepto de overrriding de métodos, que es posiblemente la característica más importante de la herencia Java.
package mypeopleexample; public class Person { public Person() { // System.out.println("Person: constructor is called"); } public Person(String name) { this.name = name; // System.out.println("Person: constructor 2 is called"); } protected String name; protected String address; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } // A method that will be overridden by sub-class public void myMethod(String t){ System.out.println("myMethod(" + t + ") in Person class"); } } |
package mypeopleexample; public class Student extends Person { public Student() { // System.out.println("Student: constructor is called"); } public Student(String name, String school, double grade) { super(name); this.school = school; this.grade = grade; // System.out.println("Student: constructor 2 is called"); } protected String school; protected double grade; public String getSchool() { return school; } public void setSchool(String school) { this.school = school; } public double getGrade() { return grade; } public void setGrade(double grade) { this.grade = grade; } // A overriding method public void myMethod(String t){ System.out.println("myMethod(" + t + ") in Student class"); } } |
package mypeopleexample; public class InternationalStudent extends Student { public InternationalStudent() { // System.out.println("InternationalStudent: constructor is called"); } public InternationalStudent(String name, String school, double grade, String country) { super.name = name; super.school = school; super.grade = grade; this.country = country; // System.out.println("InternationalStudent: constructor 2 is called"); } private String country; public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } // A overriding method public void myMethod(String t){ System.out.println("myMethod(" + t + ") in InternationalStudent class"); } } |
package mypeopleexample; public class Main { public static void main(String[] args) { System.out.println("---- Observe overriding method behavior ----"); Person person1 = new Person(); person1.myMethod("test1"); Student student1 = new Student(); student1.myMethod("test2"); InternationalStudent internationalStudent1 = new InternationalStudent(); internationalStudent1.myMethod("test3"); } } |
---- Observe overriding behavior
---- myMethod(test1) in Person class myMethod(test2) in Student class myMethod(test3) in InternationalStudent class |
public class Main { public static void main(String[] args) { System.out.println("---- Observe overriding method behavior ----"); Person person1 = new Person(); person1.myMethod("test1"); Student student1 = new Student(); student1.myMethod("test2"); InternationalStudent internationalStudent1 = new InternationalStudent(); internationalStudent1.myMethod("test3"); // Polymorphic behavior System.out.println("---- Observe polymorphic behavior ----"); Person person2 = new Student(); person2.myMethod("test4"); Person person3 = new InternationalStudent(); person3.myMethod("test5"); Student student2 = new InternationalStudent(); student2.myMethod("test6"); } } |
---- Observe overriding behavior
---- myMethod(test1) in Person class myMethod(test2) in Student class myMethod(test3) in InternationalStudent class ---- Observe polymorphic behavior ---- myMethod(test4) in Student class myMethod(test5) in InternationalStudent class myMethod(test6) in InternationalStudent class |
package mypeopleexample; public class Person { public Person() { // System.out.println("Person: constructor is called"); } public Person(String name) { this.name = name; // System.out.println("Person: constructor 2 is called"); } protected String name; protected String address; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getAddress() { return address; } public void setAddress(String address) { this.address = address; } // A method that will be overridden by sub-class public void myMethod(String t){ System.out.println("myMethod(" + t + ") in Person class"); } // A method that will be hidden by sub-class public static void myStaticMethod(String t){ System.out.println("myStaticMethod(" + t + ") in Person class"); } } |
package mypeopleexample; public class Student extends Person { public Student() { // System.out.println("Student: constructor is called"); } public Student(String name, String school, double grade) { super(name); this.school = school; this.grade = grade; // System.out.println("Student: constructor 2 is called"); } protected String school; protected double grade; public String getSchool() { return school; } public void setSchool(String school) { this.school = school; } public double getGrade() { return grade; } public void setGrade(double grade) { this.grade = grade; } // A overriding method public void myMethod(String t){ System.out.println("myMethod(" + t + ") in Student class"); } // A method that will be hidden by sub-class public static void myStaticMethod(String t){ System.out.println("myStaticMethod(" + t + ") in Student class"); } } |
package mypeopleexample; public class InternationalStudent extends Student { public InternationalStudent() { // System.out.println("InternationalStudent: constructor is called"); } public InternationalStudent(String name, String school, double grade, String country) { super.name = name; super.school = school; super.grade = grade; this.country = country; // System.out.println("InternationalStudent: constructor 2 is called"); } private String country; public String getCountry() { return country; } public void setCountry(String country) { this.country = country; } // A overriding method public void myMethod(String t){ System.out.println("myMethod(" + t + ") in InternationalStudent class"); } // A method that will be hidden by sub-class public static void myStaticMethod(String t){ System.out.println("myStaticMethod(" + t + ") in InternationalStudent class"); } } |
package mypeopleexample; public class Main { public static void main(String[] args) { System.out.println("---- Observe overriding behavior ----"); Person person1 = new Person(); person1.myMethod("test1"); Student student1 = new Student(); student1.myMethod("test2"); InternationalStudent internationalStudent1 = new InternationalStudent(); internationalStudent1.myMethod("test3"); // Polymorphic behavior System.out.println("---- Observe polymorphic behavior ----"); Person person2 = new Student(); person2.myMethod("test4"); Person person3 = new InternationalStudent(); person3.myMethod("test5"); Student student2 = new InternationalStudent(); student2.myMethod("test6"); // Calling hiding methods System.out.println("---- Observe how calling hiding methods work ----"); person2.myStaticMethod("test7"); person3.myStaticMethod("test8"); student2.myStaticMethod("test9"); } } |
---- Observe overriding behavior
---- myMethod(test1) in Person class myMethod(test2) in Student class myMethod(test3) in InternationalStudent class ---- Observe polymorphic behavior ---- myMethod(test4) in Student class myMethod(test5) in InternationalStudent class myMethod(test6) in InternationalStudent class ---- Observe how calling hiding methods work ---- myStaticMethod(test7) in Person class myStaticMethod(test8) in Person class myStaticMethod(test9) in Student class |
En este ejercicio se mostrará el casting de tipos entre tipos de clases que están relacionadas a través de la herencia.
Se puede usar el proyecto MyPeopleExample para los cambios que se van a hacer en esta sección o se puede crear un nuevo proyecto, por ejemplo, MyPeopleExampleImplicitCasting, "copiando" el proyecto MyPeopleExample - Hacer click con el botón derecho en el proyecto MyPeopleExample y seleccionar Copy Project. En lo que sigue se asume que se ha creado un nuevo proyecto.
1. Modificar the Main.java como se muestra en Código-4.11. El cambio consiste en añadir unas cuantas sentencias en las que se realiza el casting de tipo implícito entre tipos.
package mypeopleexample; public class Main { public static void main(String[] args) { System.out.println("---- Observe overriding behavior ----"); Person person1 = new Person(); person1.myMethod("test1"); Student student1 = new Student(); student1.myMethod("test2"); InternationalStudent internationalStudent1 = new InternationalStudent(); internationalStudent1.myMethod("test3"); // Polymorphic behavior System.out.println("---- Observe polymorphic behavior ----"); // This is an implicit type casting between Student and Person class. Person person2 = new Student(); // Example 1 person2 = student1; // Example 2 person2.myMethod("test4"); // This is an implicit type casting between InternationalStudent and Person class. Person person3 = new InternationalStudent(); // Example 3 person3 = internationalStudent1; // Example 4 person3.myMethod("test5"); // This is an implicit type casting between InternationalStudent and Student class. Student student2 = new InternationalStudent(); // Example 5 student2 = internationalStudent1; // Example 6 student2.myMethod("test6"); // Calling hiding methods System.out.println("---- Observe how calling hiding methods work ----"); person2.myStaticMethod("test7"); person3.myStaticMethod("test8"); student2.myStaticMethod("test9"); } } |
2. Compilar y ejecutar el programa
---- Observe overriding behavior
---- myMethod(test1) in Person class myMethod(test2) in Student class myMethod(test3) in InternationalStudent class ---- Observe polymorphic behavior ---- myMethod(test4) in Student class myMethod(test5) in InternationalStudent class myMethod(test6) in InternationalStudent class ---- Observe how calling hiding methods work ---- myStaticMethod(test7) in Person class myStaticMethod(test8) in Person class myStaticMethod(test9) in Student class |
package
mytypemismatchexampleproject; public class Main { public static void main(String[] args) { // Implicit casting - Student object instance is // type of Person. Person person1 = new Student(); // Implicit casting - Teacher object instance is // type of Person. Person person2 = new Teacher(); // Explicit type casting. Student student1 = (Student) person1; // Explicit type casting - no compile error. // But ClassCastException will occur during runtime. Student student2 = (Student) person2; } } |
Figura-4.22:
ocurrencia de java.lang.ClassCastException
package mytypemismatchexampleproject; public class Main { public static void main(String[] args) { // Implicit casting - Student object instance is // type of Person. Person person1 = new Student(); // Implicit casting - Teacher object instance is // type of Person. Person person2 = new Teacher(); // Explicit type casting. Student student1 = (Student) person1; // Do the casting only when the type is verified if (person2 instanceof Student) { Student student2 = (Student) person2; System.out.println("person2 instanceof Student = " + true); } else{ System.out.println("person2 instanceof Student = " + false); } } } |
person2 instanceof Student =
false |
En este ejercicio se ha visto cómo hacer un casting implícit y explícito entre instancias de objetos que están relacionados a través de la herencia.
Este ejercicio muestra el concepto de clase final y método final.
1. Crear un proyecto NetBeans
package myfinalclassexample; // Make the Person class as a final class public final class Person { } |
package
myfinalclassexample; /** * * @author sang */ public class Teacher extends Person{ } |
1. Crear un proyecto NetBeans
package
myfinalclassexample2; /** * * @author */ public class Teacher extends String{ } |
1. Crear un proyecto NetBeans
package
myfinalmethodexample; public class Person { // myMethod() is a final method public final void myMethod(){ } } |
package
myfinalmethodexample; public class Teacher extends Person{ // Try to override this method public void myMethod(){ } } |
En este ejercicio se ha visto que una clase final no se puede derivar y que un método final no se puede hacer overridden por una subclaseb.
En este ejercicio se desarrolla un programa simple usando varias clases que están relacionadas mediante la herencia. La clase Product
es heredadad por las clases Electronics y Book. La clase Electronics es derivada por las clases MP3Player y TV. También se ve cómo añadir comportamiento polimórfico al programa a través del overriding de métodos.
1. Crear un proyecto NetBeans
package myonlineshop; public class Product { private double regularPrice; /** Creates a new instance of Product */ public Product(double regularPrice) { this.regularPrice = regularPrice; } // Method that will be overridden public double computeSalePrice(){ return 0; } public double getRegularPrice() { return regularPrice; } public void setRegularPrice(double regularPrice) { this.regularPrice = regularPrice; } } |
package myonlineshop; public class Electronics extends Product{ private String manufacturer; /** Creates a new instance of Electronics */ public Electronics(double regularPrice, String manufacturer) { super(regularPrice); this.manufacturer = manufacturer; } // Override this method public double computeSalePrice(){ return super.getRegularPrice() * 0.6; } public String getManufacturer() { return manufacturer; } public void setManufacturer(String manufacturer) { this.manufacturer = manufacturer; } } |
package myonlineshop; public class MP3Player extends Electronics{ private String color; /** * Creates a new instance of MP3Player */ public MP3Player(double regularPrice, String manufacturer, String color) { super(regularPrice, manufacturer); this.color = color; } // Override this method public double computeSalePrice(){ return super.getRegularPrice() * 0.9; } public String getColor() { return color; } public void setColor(String color) { this.color = color; } } |
package myonlineshop; public class TV extends Electronics { int size; /** Creates a new instance of TV */ public TV(double regularPrice, String manufacturer, int size) { super(regularPrice, manufacturer); this.size = size; } // Override this method public double computeSalePrice(){ return super.getRegularPrice() * 0.8; } } |
package myonlineshop; public class Book extends Product{ private String publisher; private int yearPublished; /** Creates a new instance of Book */ public Book(double regularPrice, String publisher, int yearPublished) { super(regularPrice); this.publisher = publisher; this.yearPublished = yearPublished; } // Override this method public double computeSalePrice(){ return super.getRegularPrice() * 0.5; } public String getPublisher() { return publisher; } public void setPublisher(String publisher) { this.publisher = publisher; } public int getYearPublished() { return yearPublished; } public void setYearPublished(int yearPublished) { this.yearPublished = yearPublished; } } |
package myonlineshop; public class Main { public static void main(String[] args) { // Declare and create Product array of size 5 Product[] pa = new Product[5]; // Create object instances pa[0] = new TV(1000, "Samsung", 30); pa[1] = new TV(2000, "Sony", 50); pa[2] = new MP3Player(250, "Apple", "blue"); pa[3] = new Book(34, "Sun press", 1992); pa[4] = new Book(15, "Korea press", 1986); // Compute total regular price and total // sale price. double totalRegularPrice = 0; double totalSalePrice = 0; for (int i=0; i<pa.length; i++){ // Call a method of the super class to get // the regular price. totalRegularPrice += pa[i].getRegularPrice(); // Since the sale price is computed differently // depending on the product type, overriding // method of the object instance of the sub-class // gets invoked. This is runtime polymorphic // behavior. totalSalePrice += pa[i].computeSalePrice(); System.out.println("Item number " + i + ": Type = " + pa[i].getClass().getName() + ", Regular price = " + pa[i].getRegularPrice() + ", Sale price = " + pa[i].computeSalePrice()); } System.out.println("totalRegularPrice = " + totalRegularPrice); System.out.println("totalSalePrice = " + totalSalePrice); } } |
Item number 0: Type = myonlineshop.TV,
Regular price = 1000.0, Sale price = 800.0 Item number 1: Type = myonlineshop.TV, Regular price = 2000.0, Sale price = 1600.0 Item number 2: Type = myonlineshop.MP3Player, Regular price = 250.0, Sale price = 225.0 Item number 3: Type = myonlineshop.Book, Regular price = 34.0, Sale price = 17.0 Item number 4: Type = myonlineshop.Book, Regular price = 15.0, Sale price = 7.5 totalRegularPrice = 3299.0 totalSalePrice = 2649.5 |
En este ejercicio se ha desarrollado un programa simple que usa varias clases que están relacionadas mediante la herencia. Se ha probado un comportamiento polimórfico a través de métodos sobrecargados.