2017 - 10 -15 面向對象

1 靜態調用
   靜態方法中只能調用靜態方法,不能調用非靜態。
   可以通過創建對象調用非靜態方法
class ArrayDemo{ 
    public  static void  main(String arg[]){
           ...........
     //靜態方法
     //printArray(arr);
     //非靜態方法
     ArrayDemo ad =new ArrayDemo();
     ad.printArray(arr);
      .......
             }
    //public static void printArray(int[] arr){
                   .....
       }
    public  void printArray(int[] arr){
                   .....
      }
}

   在同一個文件夾下,類定義在兩個文件中和定義在一個文件中,其實是一樣的。
   虛擬機自動編譯其餘類文件。。。

   **把構造方法私有,外界就不能在創建對象了。。。所以只能通過靜態訪問。

2  說明書

  /**
  * 這是針對數組進行操作的工具類
  * @author XXX
  * @version V.1
  */

  /**
  * 這是遍歷數組的方法,遍歷後的格式是:{元素1,元素2,元素3}
  * @param  arr 這是要被遍歷的數組
  */
  /**
  * 這是獲取數組中最大值的方法
  * @param   arr 這是要獲取最大值得數組的數組
  * @return  返回數組中的最大值
  */
   javadoc -d 目錄 -author -version ArrayTool.java

3  jdk文檔
(1)  java.lang 包下的類不需要導入,其他的全部需要導入
   要導入:
   java.util.Scanner
(2) 記住看類的版本
(3)  類的結構
   成員變量   字段摘要
   構造方法   構造方法摘要
   成員方法   方法摘要
(4) 學習構造方法
    A:有構造方法   就創建對象
    B:沒有構造方法  成員可能都是靜態的
(5) 看成員方法
   A:左邊 
       是否靜態,如果靜態,可以通過類名調用
       返回值類型:人家返回什麼,就用什麼接收
   B:右邊
       看方法名:方法名稱不要寫錯
       參數列表:需要什麼,給什麼,需要幾個,給幾個

4  代碼塊
   代碼塊:在java中,使用{}括起來的代碼被稱爲代碼塊
   根據位置和聲明的不同,可以分爲
   局部代碼塊:局部位置,用於限定變量的生命週期
   構造代碼塊: 在類中的成員位置,用{}括起來的代碼,每次調用構造方法執行前,都會執行構造代碼塊。
          作用:可以把多個構造方法中的共同代碼放到一起。
   靜態代碼塊:在類中的成員位置,用{}括起來的代碼,只不過使用static修飾了,在有main方法的類中,優先於main執行。
          作用:一般是對類進行初始化

***面試題?

    靜態代碼塊,構造代碼塊,構造方法的執行順序

    靜態代碼塊---構造代碼塊----構造方法

    靜態代碼塊:只執行一次。

    構造代碼塊:每次調用都執行。


class Code{
   //靜態代碼塊
   static{
     int a = 1000;
     System.out.println(a);
}
   //構造代碼塊
    {
     int x = 10;
     System.out.println(x);
}
   //構造方法
   public Code(){
      System.out.println("code");
}
   //構造方法
   public Code(int a){
      System.out.println("code");
}
}

class CodeDemo{ 
    public  static void  main(String arg[]){
        //局部代碼塊
        {
           int x = 10;
           System.out.println(x);
    }
        //找不到符號
         System.out.println(x);
}

***5 看程序寫結果
class Student{
    static{
      System.out.println("Student 靜態代碼塊");
          }
    {
      System.out.println("Student 構造代碼塊");
}
     public Student(){
      System.out.println("Student 構造方法");
}
}
class StudentDemo{
    static{
      System.out.println("StudentDemo 靜態代碼塊");
   }
    public static void main(String[] args){
     System.out.println("main方法");
     Student s1 = new Student();
     Student s2 = new Student();
}
}
執行結果:
  StudentDemo 靜態代碼塊
  main方法
  Student 靜態代碼塊
  Student 構造代碼塊
  Student 構造方法
  Student 構造代碼塊
  Student 構造方法

6 java中繼承
(1)java繼承特點
  A:java只支持單繼承,不支持多繼承
  B:java支持多層繼承
(2)java繼承注意事項
  A:子類只能繼承父類所有非私有的成員(成員方法和成員變量)
   **(其實這也體現了繼承的另一個弊端:打破了封裝性)
  B:子類不能繼承父類的構造方法,但是可以通過super關鍵字去訪問父類的構造方法。
  C:不要爲了部分功能而去繼承
(3)java繼承中成員變量的關係
  A:子類中的成員變量和父類中的成員變量名稱不一樣時。
  B:子類中的成員變量和父類中的成員變量名稱一樣時,就近原則。
(4)java繼承中構造方法的關係
  A:子類中所有構造方法默認都會訪問父類中空參數的構造方法
  B:爲什麼?
    因爲子類會繼承父類中的數據,可能還會使用父類的數據。
    所以,子類初始化之前,一定要先完成父類數據的初始化。
    **注意:子類每一個構造方法的第一條語句默認都是:super();
(5)java繼承中構造方法的注意事項
    如果父類沒有無參數的構造方法,那麼子類的構造方法會出現什麼現象呢?
    報錯!
    如何解決?
    A:在父類中加一個無參數的構造方法。
    B: 通過使用super關鍵字去顯示的調用父類的帶參構造方法
    C:子類通過this去調用本類的其他構造方法
         子類中一定要有一個去訪問了父類的構造方法,否則父類數據就沒有初始化
    **注意事項:super()或者this()必須出現在第一條語句上
                否則,就會有父類數據的多次初始化
(6)java繼承中成員方法的關係:
    A:子類中的方法和父類中的方法聲明不一樣時。
    B:子類中的方法和父類中的方法聲明一樣時。
         通過子類調用方法:
            a:先找子類中,有沒有這個方法,有就使用。
            b:再看父類中,有沒有這個方法,有就使用。
            c:如果都沒有就報錯。


***7 繼承中的面試題
    A:成員變量的問題
      int x = 10;                //成員變量是基本類型
      Student s = new Student(); //成員變量是引用類型
    B:一個類的初始化過程
          成員變量的初始化
          默認初始化
          顯示初始化
          構造方法初始化
    C:子父類的初始化(分層初始化)
       先進行父類初始化,然後進行子類初始化
 
  class X{
         Y b = new Y();
         X(){
           System.out.print("X");
     }
}
  class Y{
       Y(){
         System.out.print("Y");
     }
}
  public class Z extends X{
        Y y = new Y();
        Z(){
            //super();
            System.out.print("Z");
 }
         public static void main(String[] args){
          new Z();
    }
}
    輸出結果: YXYZ
    有super出現問題:
       雖然子類中構造方法默認有一個super();
       初始化的時候,不是按照那個順序進行的。
       而是按照分層初始化進行的。
       它僅僅表示要先初始化父類數據,再初始化子類數據

8 重寫

(1)方法重寫
   子類中出現了和父類中方法聲明一模一樣的方法。
   方法重載
   本類中出現的方法名一樣,參數列表不同的方法,與返回值無關。

(2)方法重寫的注意事項
    A:父類中私有方法不能被重寫
           因爲父類私有方法子類根本就無法繼承
 ***B:子類重寫父類方法時,訪問權限不能更低
           最好就一致
    C:父類靜態方法,子類也必須通過靜態方法進行重寫
           其實這個算不上重寫,但現象確實如此,多態中會介紹。

   java中靜態變量和靜態方法可以被繼承,但是沒有被重寫而是被隱藏。

   通過子類調用父類的同名的靜態成員變量或方法,依然訪問的是父類的變量和方法。

   而且,靜態不能使用this和super關鍵字。


***9兩個面試題
(1)方法重寫(Override)和方法重載(Overload)的區別?方法重載能改變返回值類型嗎?
      方法重寫:在子類中,出現和父類中一模一樣的方法聲明的現象。
      方法重載:同一個類中,出現的方法名相同,參數列表不同的現象。
      方法重載能改變返回值類型,因爲它和返回值類型無關。
(2)this關鍵字和super關鍵字分別代表什麼?以及他們各自的使用場景和作用。
   this:代表當前類的對象引用
   super:代表父類存儲空間的標識(可以理解爲父類的引用,通過這個東西可以訪問父類的成員)
   場景:
     成員變量:
         this.成員變量
         super.成員變量
     構造方法:
         this(...)
         super(...)
     成員方法:
         this.成員方法
         super.成員方法
    
10  final
 (1)由於繼承中方法有一個現象:方法重寫
    所以,父類的功能,就會被子類給覆蓋掉。
    有些時候,我們不想讓子類去覆蓋掉父類的功能,只能讓他使用
    這個時候,針對這種情況,java就提供了一個關鍵字final
    
 (2)  final 可以修飾類,方法,變量
    特點:
      final可以修飾類,該類不能被繼承
      final可以修飾方法,該方法不能被重寫
      final可以修飾變量,該變量不能被重新賦值,因爲這個變量其實是常量。

 (3)   常量
       A:字面值常量
         " hello" ,10,true
       B:自定義常量
          final int x = 10

***11  final面試題

  (1) final修飾局部變量的問題

       基本類型:基本類型的值不能發生改變

       引用類型:引用類型的地址值不能發生改變,但是該對象的堆內存的值可以發生改變

    class Student{
          int age =10;
 }
    class FianlTest{
      public static void main(String[] args){
           //局部變量是基本數據類型
           final int y = 10;
           //無法爲最終變量y分配值
           //y = 100;
           //局部變量是引用類型
           Studnet s = new Student();
           System.out.println(s.age);
           s.age = 100;
           System.out.println(s.age);
           //輸出 10 100
           
           final Student ss =new Student();
           System.out.println(ss.age);
           ss.age = 100;
           System.out.println(ss.age);
           //輸出 10 100
          
           //重新分配內存空間
           //報錯,無法爲最終變量ss分配值

           ss = new Student();


    (2)final 修飾變量的初始化時機
           A:被final修飾的變量只能賦值一次
           B:在構造方法完畢前。(非靜態的常量)
A:
  class Demo{
        int num = 10;
        final int num2 = 20;
        public Demo(){
            num = 100;
         }
}
   class FinalTest2{
          public static void main(String[] args){
             Demo d = new Demo();
             System.out.println(d.num);
}
}
       輸出結果爲:100 (先初始化成員變量,再初始化構造方法)
  
B:
  class Demo{
        int num = 10;
        final int num2 = 20;
        
        public Demo(){
            num = 100;
            //無法爲最終變量num2分配值 會報錯
            num2 = 200
}
}
   class FinalTest2{
          public static void main(String[] args){
             Demo d = new Demo();
             System.out.println(d.num);
             System.out.println(d.num2);
}
}
       輸出結果:報錯

C:
  class Demo{
        //int num = 10;
        //final int num2 = 20;
        int num;
        final int num2 ;
        public Demo(){
            num = 100;
            num2 = 200
}
}
   class FinalTest2{
          public static void main(String[] args){
             Demo d = new Demo();
             System.out.println(d.num);
             System.out.println(d.num2);
}
}
         輸出結果:100 200


D:
  class Demo{
        int num;
        final int num2 ;
    {
        num2= 10;     
}
        public Demo(){
            num = 100;
            num2 = 200
}
}
   class FinalTest2{
          public static void main(String[] args){
             Demo d = new Demo();
             System.out.println(d.num);
             System.out.println(d.num2);
}
}
     輸出結果:報錯 (代碼塊中已經賦值了)
發佈了31 篇原創文章 · 獲贊 2 · 訪問量 9207
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章