Java - 一個繼承與多型下動態轉型的例子

在這邊要提到的是繼承與多型下的動態轉型應用,透過一個共用的方法,並依據pass的class

name來動態轉型父類別,此實體再呼叫其下相關的getter method取值後得到比較的結果。

首先,我們制訂了一個抽象類別AbstractBook

  1. abstract class AbstractBook{
  2. public abstract String showInfo();
  3. }

這個抽象類別定義了一個抽像方法,此方法在子類別繼承AbstractBook,必須override來重新

定義他的行為。

子類別 - ReferenceBook
  1. class ReferenceBook extends AbstractBook{
  2. private String r_publishing;
  3. private String r_name;
  4. public String getR_publishing() {
  5. return r_publishing;
  6. }
  7. public void setR_publishing(String r_publishing) {
  8. this.r_publishing = r_publishing;
  9. }
  10. public String getR_name() {
  11. return r_name;
  12. }
  13. public void setR_name(String r_name) {
  14. this.r_name = r_name;
  15. }
  16. public String showInfo(){
  17. return this.getR_name()+"\t參考書("+this.getR_publishing()+")";
  18. }
  19. }

另外定義了自行的成員變數r_pubshing為發行日期、r_name為名稱

子類別 - Magazine
  1. class Magazine extends AbstractBook{
  2. private String m_publishing;
  3. private String m_name;
  4. public String getM_publishing() {
  5. return m_publishing;
  6. }
  7. public void setM_publishing(String m_publishing) {
  8. this.m_publishing = m_publishing;
  9. }
  10. public String getM_name() {
  11. return m_name;
  12. }
  13. public void setM_name(String m_name) {
  14. this.m_name = m_name;
  15. }
  16. public String showInfo(){
  17. return this.getM_name()+"\t雜誌本("+this.getM_publishing()+")";
  18. }
  19. }

另外定義了自行的成員變數m_pubshing為發行日期、m_name為名稱

PS. 發行日期及名稱在這邊由各類別自行定義,配合override's showInfo method來表達該

method要定義的資訊顯示方式。

主體程式

  1. public static void main(String[] args) {
  2. // TODO Auto-generated method stub
  3. try{
  4. System.out.println("書名 \t類別(出版日期) \t是否出版?");
  5. System.out.println("===============================================");
  6. AbstractBook obj1 = new Magazine();
  7. Magazine nobj1 = (Magazine) obj1;
  8. nobj1.setM_publishing("2015/01/30");
  9. nobj1.setM_name("空眾英文雜誌");
  10. isPublished(obj1, Magazine.class, "getM_publishing");
  11. AbstractBook obj2 = new ReferenceBook();
  12. ReferenceBook robj2 = (ReferenceBook) obj2;
  13. robj2.setR_publishing("2015/03/17");
  14. robj2.setR_name("Java初學手冊");
  15. isPublished(obj2, ReferenceBook.class, "getR_publishing");
  16. } catch(Exception e){
  17. e.printStackTrace();
  18. }
  19. }
  20. public static void isPublished(AbstractBook book,Class<?> myclass,String ...methodName){
  21. SimpleDateFormat dateformat = new SimpleDateFormat("yyyy/MM/dd");
  22. Method m = null;
  23. try{
  24. Object obj = myclass.cast(book);
  25. m = obj.getClass().getDeclaredMethod(methodName[0]);
  26. String cdate = dateformat.format(new Date());
  27. Date current = dateformat.parse(cdate);
  28. Date publish = dateformat.parse(m.invoke(obj).toString());
  29. if(current.after(publish)){
  30. System.out.println(book.showInfo()+"\tYES");
  31. }else{
  32. System.out.println(book.showInfo()+"\tNO");
  33. }
  34. } catch(Exception e){
  35. e.printStackTrace();
  36. }
  37. }

首先,利用父類別宣告一物件名,並且實體來自其下的子類別

在這邊為is-a關係方式,即Magazine或ReferenceBook is-a AbstractBook

因此參數book可以操作Magazine's method或ReferenceBook's method為多型的一種表現!!

當然,在參數book能夠取用各自子類別的方法時,還必須透過轉型才可以,如下:

Magazine obj = (Magazine) book;

or

ReferenceBook obj = (ReferenceBook) book;

但是,在isPublished method內,為了要通用各個子類別來轉型,所以就要動態轉型的方式。

因此,在參數2將帶入各個子類別的Magazine.class or ReferenceBook.class等類別物件

PS. 以ClassName.class表示 Returns the runtime class of this Object. By Java Doc.

最後,將得到結果如下:


留言