JAVA 類的繼承/抽象/接口/多態性

/*
類的繼承
類的繼承可以簡化類的定義
java只支持單繼承,不允許多重繼承
可以有多層繼承,即一個類可以繼承其一個類的子類,如類B繼承了類A,類C又可以繼承類B
那麼類C也間接繼承了類A
  
子類繼承父類所有的成員變量和成員方法,但不繼承父類的構造方法,
在子類的構造方法中可使用語句super(參數列表)
調用父類的構造方法
  
如果子類的構造方法中沒有顯式地調用父類構造方法,也沒用使用this關鍵字調用重載的其它構造方法,則在產生子類的實例對象時
系統默認調用父類無參數的構造方法
  
子類對象的實例化過程
  
1 分配成員變量的存儲空間並進行默認的初始化,就是用new關鍵字產生對象後
  對類中的成員變量按第三章的表3.1的對應關係對對象中的成員變量進行初始化賦值
  
2 綁定構造方法參數,就是new Person(實際參數列表)中所傳遞進的參數賦值給構造方中的形式參數變量
  
3 如果有this()調用,則調用相應的重載構造方法(被調用的重載構造方法又從步驟2開始執行這些流程)
  被調用的重載構造方法的執行流程結束後,回到當前構造方法,當前構造方法直接跳轉到步聚6執行
  
4 顯示或隱式追溯調用父類的構造方法(一直到Ojbect類爲止,Object是所有java類的最頂層父類)
  在本音後面部分有詳細講解,父類的構造方法又從步驟2開始對父類執行這些流程,父類的構造方法的執行流程結束後,回到當前構造方法,當前構造方法繼承往下執行
  
5 進行實例變量的顯示初始化扣喺,也就是執行在定義成員變量時就對其進行賦值的語句
  
6 執行當前構造方法的方式體中的程序代碼
  
1):爲什麼super()和this()調用語句不能同時在一個構造函數中出現?
   因爲當在一個構造函函數中出現this()調用以後,那麼去別外一個構造函數將也會直接默認或指定的super()方法
   如要執行完成以後,返回到初始的構造函數還讓執行super()方法時,那就又是重複操作了,無意義
   所以編譯也不會通過的
  
  
2):爲什麼super()和this()調用語句只能作爲構造函數的第一句出現
   如果不是作爲第一句出現,編譯也會出錯的
   如果選執行一些賦值語句,然後執行this或super()函數
   那麼就跟我們的執行流程相矛盾了
   因爲構造函數需要需要執執行this,如果沒有this執行super()方法
   編譯器也不會讓通過的
  
  
覆蓋父類的方法
   覆蓋方法必須和被覆蓋方法具有相同的方法名稱,參數列表和返回值類型
  
   如果在子類中想調用父類中那個被覆蓋的方法,我們可以用super方法的格式
  
   覆蓋方法時,不能使用此父類中被覆蓋的方法更嚴格的訪問權限
  
     
final關鍵字
   1 在java中聲明類,屬性和方法時,可以使用關鍵字final來修飾
   2 final標記的類不能被繼承
   3 final標記的方法不能被子類重寫
   4 final標記的變量(成員變量或局部變量)即成爲常量,只能賦值一次
   5 方法中定義的內置類只能訪問該方法內的final類型的局部變量
     用final定義的局部變量相當於是一個常量,它的生命週期超出了方法運行的重命週期
     將一個行參定義成final也是可以的,這就是限定了我們在方法中修改形式參數的值
   6 public static final共同標記常量時,這個常量就成了全局常量
  
抽象類
   java中可以定義一些不含方法體的方法,它的方法體的實現交給該類的子類根據自己的情況去實現
   這樣的方法就是抽象方法,包含抽象方法的類叫做抽象類
  
   1 抽象類必須使用abstract關鍵字來修飾,抽象方法也必須用abstract來修飾
   2 抽象類不能被實例化,也就是不能用new關鍵字去產生對象
   3 抽象類只需聲明,而不需實現
   4 含有抽象方法的類必須聲明爲抽象類,抽象類的子類必須覆蓋所有抽象方法後才能被實例化,否則這個子類還是個抽象類
  
*/
  
//final class Person 將不能被繼承了
class Person
{
    //protected final String name = "unknown"; 變量爲final時將不能被子類賦值了
    protected String name = "unknown";
  
  
    //public final String x = "abc"; //第一種賦值是初始賦值
  
    public  final String x;
    //public static final String x;
  
    public static final String y = "abc";
  
  
  
  
    public int age = -1;
  
    public Person()
    {
        this.x = "cde";
    }
  
    public Person(String name, int age)
    {
        this.name = name;
        this.age = age;
        //或者在構造函數中進行賦值
        this.x = "abc";
  
    }
  
    //public void getInfo(){} 將不能在子類重寫了
    public void getInfo()
    {
        //this.x = "abc"; //用final定義的變量將不能被修改了
        System.out.println("name:"+name+", age:"+age);
    }
};
  
  
class Student extends Person
{
  
    public String school = "unknown";
  
    public Student()
    {
        //super("xlc",15);
        super();
    }
  
    public Student(String name, int age, String school)
    {
         
        this(name,age); //調用自己的構造函數
        this.school = school;
        //this(name,age); //調用自己的構造函數
    }
  
    public Student(String name, int age)
    {
         super(name, age);
    }
  
    public void getInfo()
    {
         System.out.println("school:"+school+"name:"+name+", age:"+age);
         super.getInfo();
    }
  
    public void study()
    {
      
    }
};
  
class TestStudent
{
    public static void main(String[] args)
    {
          
        //Student st = new Student();
        //st.name = "xlc";
        //st.age = 34;
        //st.getInfo();
  
        Student st = new Student("xlc",22,"清華大學");
        st.getInfo();
  
        System.out.println(Float.MAX_VALUE);
    }
};

  

/*
接口(interface)
如果一個抽象類中的所有方法都是抽象的,我們就可以將這個類用另外一種方式來定義,也就是接口定義
接口是抽象方法和常量值的定義的集合,從本質上講,接口是一種特殊的抽象類
這種抽象類中只包含常量和方法的定義,而沒有變量和方法的實現
  
1 接口中的成員都是public訪問類型的,接口的變量默認是用public static final標識的
  
2 我們可以定義一個新的接口用extends 關鍵字去繼承一個已有的接口
  
3 我們也可以定義一個類用implements關鍵字去實現一個接口中的所有方法,我們還可以去定義一個抽旬類用implements關鍵字去實現一個接口中定義的部分方法
  
4 一個類可以繼承一個父類的同時,實現一個或多個接口,extneds關鍵字必須位於implements關鍵字之前
  
  
對象的類型轉換
   1 子類對象可以自動轉換成父類
   2 父類轉換爲子類必須使用強制轉換
   3 instanceof操作符可以用它來判斷一個實例對象是否屬於一個類
   4 Object類及equals方法
  
  
*/
/*abstract class A
{
    abstract int aa(int x, int y);
  
    //抽象類將不能實例化
  
  
};
  
  
class B extends A
{
     int aa(int x, int y)
     {
       
         return 1;
     }
};*/
  
  
interface Runner
{
    int ID = 1;
  
    void run();
}
  
interface Animal extends Runner
{
     void breathe();
}
  
  
class Fish implements Animal
{
     public void run()
     {
         System.out.println("fish is swimming");
     }
  
     //public void breathe()
     public void breathe()
     {
         System.out.println("fish is bubbling");
     }
  
     public static void main(String[] args)
     {
          Fish f = new Fish();
          int j=0;
          j = Runner.ID;
          j = f.ID;
          //f.ID = 2; //常量不能被賦值
  
     }
};
  
abstract class LandAnimal implements Animal
{
    public void breathe()
    {
      
    }
};
  
  
  
interface dog
{
     void uaau();
}
  
interface Flyer
{
     void fly();
}
  
class Bird implements Runner, Flyer
{
    public void run()
    {
      
    }
  
    public void fly()
    {
      
    }
};
  
  
  
  
//繼承一個類時,可以實現其它接口
//也是可以繼承從外接口類的
class Student extends Person implements Runner, dog
//如果繼承類和接口,extends必須在implements之前
{
      
    public void run()
    {
      
    }
  
    public void uaau()
    {
      
    }
};
  
  
interface
{
    //public static final int ID=1;
    //int ID = 1; //這個是一個常量而不是一個變量,接口只能定義常量,不能定義變量,
    //只能定義常量和抽象類
  
    public static final int ID=1;
  
    int aa(int x, int y);
  
    void bb();
}
  
  
  
  
  
  
/*class  
{
    public static void main(String[] args) 
    {
        System.out.println("Hello World!");
    }
}*/

  

/*
面向對象的多態性
1):應用程序不必爲每一個派生類(子類)編寫功能調用
只需要對抽象基類進行處理即可,這一招叫"以不變應萬變",可以大大提高程序的可複用性
  
2):派生類的功能可以被基類的引用變量引用,這叫向後兼容,可提高程序的可擴充性和可維護性
   以前寫的程序可以被後來程序調用不足以爲奇,現在寫的程序(如callA方法)能調用以後寫的程序(以後編寫的一個類A的子類,如類D)就了不起了
  
  
*/
class A
{
    public void func1()
    {
        System.out.println("A func1 is calling");
    }
  
    public void func2()
    {
        func1();
    }
};
  
class B extends A
{
    public void func1()
    {
        System.out.println("B func1 is calling");
    }
  
    public void func3()
    {
        System.out.println("B func3 is calling");
    }
};
  
class C
{
    public static void main(String[] args)
    {
          
        B b = new B();
        callA(b);
  
        //A aa = b;
        //callA(new A());
    }
  
    public static void callA(A a)
    {
        /*if(a instanceof B)
        {
          B b = (B)a; //強制類型轉換
          b.func1();
          b.func2();
          b.func3();
        }else{
          a.func1();
          a.func2();
        }*/
  
  
        a.func1();
        a.func2();
  
        //a.func1();
        //a.func2();
        //a.func3();
    }
};
  
  
class Student extends Object
{
  
     private String name;
  
     private int age;
  
     public Student(String name, int age)
     {
         this.name = name;
         this.age = age;
     }
  
  
     /*public boolean equals(Object obj)
     {
          Student st = null;
          if(obj instanceof Student)
          {
               st = (Student)obj;
               if(st.name == name && st.age == age)
               {
                  return true;
               } else{
                  return false;
               }
          }else{
               return false;
          }
     }*/
     //如果沒有覆蓋父類的equals方法,那麼將返回不等
     //只是重載了一下函數
  
     public static void main(String[] args)
     {
         Student st1 = new Student("張三",20);
         Student st2 = new Student("張三",20);
         if(st1.equals(st2))
         {
             System.out.println("相等");
         }else{
             System.out.println("不相等");
         }
     }
  
};
  
  
  
/*class  
{
    public static void main(String[] args) 
    {
        System.out.println("Hello World!");
    }
}*/

  

interface PCI
{
   void start();
  
   void stop();
  
}
  
class NetWrokCard implements PCI
{
    public void start()
    {
        System.out.println("Send...");
    }
  
    public void stop()
    {
        System.out.println("stop...");
    }
};
  
  
class SoundCard implements PCI
{
    public void start()
    {
        System.out.println("du...");
    }
  
    public void stop()
    {
        System.out.println("sound stop...");  
    }
};
  
class MainBoard
{
    public void usePCICard(PCI p)
    {
        p.start();
        p.stop();
    }
};
  
class Assembler
{
  
    public static void main(String[] args)
    {
         MainBoard mb = new MainBoard();
  
         NetWrokCard nc =  new NetWrokCard();
  
         SoundCard sc = new SoundCard();
  
         mb.usePCICard(nc);
         mb.usePCICard(sc);
  
         //匿名類
         /*mb.usePCICard(
           new PCI()
           {
                public void start()
                {
                   System.out.println("test start...");
                
  
                public void stop()
                {
                   System.out.println("test end...");
                }
           }             
         );*/
  
         //類擬於
         class A implements PCI
         {             
                public void start()
                {
                   System.out.println("test start...");
                
  
                public void stop()
                {
                   System.out.println("test end...");
                }
  
         };
         mb.usePCICard(new A());
  
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章