20155219 2016-2017-2 《Java程序設計》第4周學習總結

20155219 2016-2017-2 《Java程序設計》第4周學習總結

教材學習內容總結

  • 抽象方法與抽象類
    若是某方法區塊中沒有任何程序代碼操做,可使用abstract在class以前,表示該方法爲抽象方法,不用撰寫{},直接;結束便可。表示這個類定義不完整,所以不能用來生成實例。
public abstract class i {
   public abstract void fight();
   i aa=new i();
}

上述代碼會出現以下錯誤image
若是子類要繼承抽象父類,那麼它必須繼續標示該方法爲abstract,或者是操做抽象方法。html

  • protect成員:對於private語句,若是你只想讓子類能夠直接存取,可使用protect語句。被聲明爲protect的成員,相同包中的類能夠直接存取,不一樣包中的類能夠在繼承後的子類中存取。
public String toString()
    {
        return String.format("劍士(%s,%d,%d)",this.name,this.blood,this.level);
    }

(若是方法中沒有同名函數,this能夠省略)
如上代碼段,(其中String.format語句:String類的format()方法用於建立格式化的字符串以及鏈接多個字符串對象。詳見以下連接).在父類中定義以下函數,便可引用子類的函數。java

public static void  drawFight(d role)
    {
        System.out.println(role.toString());
    }

至此,已經學習了java中關於權限的三個關鍵字,分爲四個權限範圍,以下表git

關鍵字 類內部 相同包內 不一樣包類
public 可存取 可存取 可存取
private 可存取 不可存取 不可存取
protected 可存取 可存取 不可存取但子類可存取
可存取 可存取 不可存取
  • super()關鍵字的使用
    若是想去的父類中定義的方法,能夠在調用方法前加上super關鍵字。注意:可使用super關鍵字調用的父類方法不能定義爲private。從新定義方法是要注意,對於父類的方法權限,只能擴大但不能縮小。(關於子類的static成員:若是子類中定義了相同簽署的static成員,該成語屬於子類全部而非從新定義,static方法也沒有多態。)
  • 構造函數:建立子類實例後,會先執行父類中構造函數定義的流程,在執行子類中構造函數定義的流程。父類中能夠重裁多個構造函數,若是子類構造函數中沒有指明使用父類中哪一個構造函數,默認會調用父類中無參數構造函數。
    以下代碼
public class i{
    public static void main(String[] args) {
        other ss=new other();
        ss.toString();
    }
        static class a{
            a()
            {
                System.out.println("some()被調用");
            }
            a(int i)
            {
                System.out.println("some(int i)被調用");
            }
        }
        static class other extends a
        {
            other()
            {
                super();
                System.out.println("other()被調用");
            }
        }
    }

結果如圖image在new other()時,先調用了other版本的構造函數,super(10)表示調用父類some(int i)版本的構造函數,故有上述輸出。若是子類在構造函數中沒有指定執行父類中的那個構造函數,默認會調用父類中無參數構造函數。以下代碼段會顯示編譯出錯bash

static class a{
            a(int i)
            {
                System.out.println("some(int i)被調用");
            }
        }
        static class other extends a
        {
            other()
            {
                System.out.println("other()被調用");
            }

以下image由於父類中定義了a(int i)構造函數,不會自動加入任何構造函數,而子類默認調用父類中無參數的構造函數,所以編譯失敗。(若是定義了有參數的構造函數,也能夠加入無參數構造函數爲往後使用上的彈性)。ide

  • final類不能被繼承在構造函數執行流程中,必定要有對該數據成員指定值的動做,不然編譯出錯。
  • java中,子類只能繼承一個父類,若是定義時沒有使用關鍵字extends,那就必定是繼承了java.lang.object。所以以下撰寫程序是合法的
Object o1="taylor swif";
Object o2=new Data() ;
  • 從新定義tostring()
    許多方法傳入對象,默認都會調用toString(),以下代碼
System.out.println(swords.toString());
System.out.println(swords);

是相同的。函數

  • 對於instanceof運算符,它能夠用來判斷對象是否由某個類建立。左操做數是對象,右操做數是類。在執行時,只要左操做數是右操做數類型的子類型,返回值也是true。
  • 接口定義行爲
    以下代碼
public interface swimmer {
    public abstract void swim();
}
package src.week3;
public class human implements swimmer{
    public static void main(String[] args) {
        human a=new human("hjasdh");
        a.swim();
    }
    private String name;
    public human(String name)
    {
        this.name=name;
    }
    public String getName()
    {
        return name;
    }
    @Override
    public void swim()
    {
        System.out.printf("人類%s游泳%n",name);
    }
}

human操做了swimmer,因此都擁有Swimer定義的行爲,但他們沒有繼承Fish。類要操做接口,必須使用implement關鍵字,操做某接口時,對接口中定義的方法有兩種處理方式,一是操做接口中定義的方法,二是再度將該方法表示爲abstract。注意:java中子類只能繼承一個父類。學習

  • 行爲的多態
    只要是操做Swimmer接口的對象,均可以使用範例中doswim()方法,代碼以下:
public class Ocean {
    public static void main(String[] args) {
        doswim(new human("ads"));
        doswim(new shark("ads"));
        doswim(new submarine("ads"));
    }
    static void doswim(swimmer a)//只要對象擁有Swimer行爲,就能夠直接引用,無需作新的方法撰寫
    {
        a.swim();
    }

在java中類能夠操做兩個以上的類,擁有兩種以上的行爲。代碼以下:ui

public class airplane implements swimmer,flyer{}
  • 接口語法細節:
    在java中,可使用interface來定義抽象的行爲與外觀,接口中的方法能夠聲明爲
public abstract void swim(){}
  • 接口中的方法沒有操做時,能夠省略public和abstract。須要注意的是:在以後使用這個接口時,若是要增長語句,必須在方法前加入public聲明,不然默認爲包權限,將public的方法權限縮小,會編譯失敗。以下:image
  • 在interface中,能夠定義常數,但只能是public static final的枚舉常量類型。故在接口中枚舉常量,必定要使用=指定值,不然就會編譯出錯。
  • 類能夠操做兩個以上的接口,若是有兩個以上的接口都定義了某種方法,編譯能夠經過。但若是其定義的方法名稱相同但要表示的是不一樣的操做方法,那麼其名稱就應該有所不一樣。若是表示相同方法,便可定義一個父接口,具體代碼以下:
interface Action {
    void execute();
}
interface  some extends Action{
    void dosome();
}
interface  other extends Action{
    void doother();
}
public class n implements some,other{
    public static void main(String[] args) {
        n aa=new n();
        aa.dosome();
        aa.doother();
        aa.execute();
    }
    @Override
    public void execute()
    {
        System.out.println("execute");
    }
    @Override
public void dosome()
    {
        System.out.println("some");
    }
    @Override
    public void doother()
    {
        System.out.println("other");
    }
}

接口能夠繼承別的接口,也能夠同時使用兩個以上的接口,一樣是使用extends關鍵字。this

  • 內部類與匿名內部類

成員內部類定義在成員位置上,局部內部類定義在局部位置與方法上。內部類的成員能夠直接訪問外部的成員,而外部類要訪問內部類,必須創建內部類對象。當內部類定義了static成員,該內部類必須是static。局部內部類方文局部變量必須用final修飾,由於局部變量會隨着方法的調用而被調用,隨着方法調用完畢而消失,加上final後,這個變量就變成了常量。匿名內部類是一個繼承了該類或者是實現了該接口的子類匿名對象。它必須繼承一個類或者是實現了接口。格式爲new 父類或者接口(){重寫方法}。能夠將其理解爲帶內容的對象。匿名內部類中定義的方法最好不要超過三個。.net

  • 若是子類複寫了父類的方法,調用此方法的時候先找子類方法。複寫即爲:子類繼承父類相同的方法,但有別於父類相對應得方法時就會覆蓋父類的方法。(相同參數,不一樣實現)
  • 重寫方法規則:1.參數列表必須徹底與被重寫的方法相同,不然只能是重裁。2.返回類型必須與被重寫的返回類型相同,不然是重裁。3.方法權限修飾符必須大於被重寫的方法修飾符(public>protected>default>private)
  • 重裁方法規則:1.必須具備不一樣的參數列表。2.能夠有不一樣的返回類型。3.能夠有不一樣的訪問修飾符。

教材學習中的問題和解決過程

  • xx1問題:爲何以下代碼段會編譯出錯?
f jiansh=new d();//d類是父類,f類是子類。這行代碼編譯出錯。
  • xx1解決方案:子類是父類的繼承,編譯器檢查語法邏輯是否正確,方式是從等號右邊往左邊讀:右邊是不是一種左邊。對於上述代碼d類是父類,f類是子類。f是一種d,但d不必定是一種f。故有以下代碼:
public class f  extends d{
    public static void main(String[] args) {
        fight();
    }
    public static void fight(){
        System.out.println("揮劍攻擊");
        d role1=new f();//
        f jianshi=(f) role1;//告訴編譯程序,f是一種d。
        f jiansh=new d();//
    }
    }

其中第11行代碼編譯成功,由於你告訴編譯程序,f是一種d。

  • xx2問題:對於教材P169頁,爲何編譯程序後發現SwordMan沒有輸出「揮劍攻擊」?
  • xx2解決方案:教材給予說明,傳入drawFiht()的是SwordMan類型,那麼role參考的就是SwordMan實例,同時在從新定義父類中某個方法時,子類必須撰寫與父類相同的簽署,書上錯例即在子類中的簽署與父類因粗心寫錯而形成的編譯錯誤。想避免此類錯誤,能夠在子類中某個方法錢標註@overrideimage就會出現如上圖的錯誤提醒。

代碼調試中的問題和解決過程

  • xx1問題:以下代碼
package src.week3;
public class RPG {
    public static void main(String[] args) {
        f qq=new f();
        qq.setName("Justin");
        qq.setLevel(1);
        qq.setBlood(200);
        showblood(qq);
        a bb=new a();
        showblood(bb);
    }
    static void showblood(d role)
    {
        System.out.printf("%s血量 %d%n",role.getName(),role.getBlood());
    }

沒法從bb包內取得信息,不然編譯不經過,上述代碼能夠獲得以下結果:
image同時能夠藉此回顧上一週學的字符串初始化爲null。

  • xx1解決方案:通過一番查找,我發現了問題所在。以下圖
  • image, 文件名上有小紅叉,但依然能夠運行,只是沒法繼承父類。通過上網百度,發現緣由是不當心把一些.iml文件誤刪了,去回收站還原以後便可正常編譯。以下:
  • image
  • xx2問題:關於書上代碼guest.java的錯誤與改正。錯誤代碼以下:
package src.week3;
import java.util.Scanner;
public class guest {
    public static void main(String[] args) {
        k name1=new k();
        collectnameto(name1);
        System.out.println("訪客名單:");
        pp(name1);
    }
    public static  void collectnameto(k names)
    {
        while(!(names.equals("quit"))){
            System.out.print("訪客姓名: ");
            Scanner console=new Scanner(System.in);//新建一個Scanner實例
            String name=console.nextLine();
            if(names.equals("quit"));
            break;
        }
        names.add(names);//收集name
    }
    public   static  void  pp(k name1)
    {
        for(int i=0;i<name1.size();i++)
        {
            String name=(String) name1.get(i);
            System.out.println(name.toUpperCase());
        }
    }
}

此代碼只能輸入一次,雖能夠編譯但運行出錯。image提示錯誤所在代碼以下

String name=(String) name1.get(i);

因此索性直接改成

System.out.println(name1.get(i));

但輸出變成image想着是呀忘了把它轉換成String類型就直接輸出了。因而繼續修改

System.out.println((String) name1.get(i));

但仍是出錯,如圖:image根據輸出判斷應該和第一次代碼的錯誤相同。估計錯誤不在此處,因而與書上比較是否有粗心輸錯的地方,果真我把

name1.add(cc);

放到了循環外側,因而把語句拖入循環中,覺得應該對了,結果直接出錯以下:imageUNreachable statement的意思是不能到達的語句。我想是否是他的位置有問題,就把它移到了if()語句上面,能夠編譯和運行了,可是隻能輸入一個名字,如圖:image我想確定是循環哪裏出了毛病,因而在這個函數開頭設斷點開始單步調試,一開始都是正確的以下圖:image但在下一步就是

if(cc.equals("quit"));
            {
                break;
            }

語句處,明明不相等的兩個語句,可是卻break了。因而我開始着手解決if()條件語句。嘗試屢次都在出錯,錯誤都是相同的就是直接跳出循環。此處的問題還沒搞清楚。因而放棄if()語句,將代碼段修改以下

public static void collectnameto(k name1)
    {int i=0;
        Scanner console=new Scanner(System.in);//新建一個Scanner實例
        while (i==0){
            System.out.printf("訪客姓名: ");
            String cc=console.next();
            console.nextLine();
            name1.add(cc);
            i=ww(cc);
        }
    }
    public  static int ww(Object o)
    {
        if(o.equals("quit"))
            return 1;
        else
            return 0;
    }

顯示正確。最後能夠正確輸入與輸出以下圖:image最後關於

cc=console.next();
console.nextLine();

語句,我曾懷疑是這裏出錯,上網百度後,發現了.nextLine()和.next()其實沒什麼大的分別,但可能出現吃回車問題,因而我在cc=console.next();語句後又加入了console.nextLine();能夠避免這個問題。

代碼託管

  • 代碼提交過程截圖:
    • 運行 git log --pretty=format:"%h - %an, %cd : %s" 並截圖image
  • 代碼量截圖:
    • 運行 find src -name "*.java" | xargs cat | grep -v ^$ | wc -l 並截圖

上週考試錯題總結

  • 錯題及緣由:
    「30」轉化爲byte類型的30,語句是(Byte.parseByte(「30」);)
  • 理解狀況:java.lang.Byte.parseByte()方法的做用是將字符串參數轉化爲帶符號的十進制數。
  • 錯題2及緣由:Linux bash中(grep)命令能夠進行全文搜索?
  • 理解狀況:grep命令的主要功能就是進行字符串數據的對比,能夠搜索文本,並將符合用戶需求的字符串打印出來。
  • 錯題3:
public class Game {
    public static void main(String[] args) {
        System.out.println(""+52+25);
        System.out.println(52+25+"");
    }
    }

對上述代碼的輸出理解

  • 理解狀況:輸出如圖:image
    System.out.println(""+i);等同於 System.out.println(i.tostring());返回對象的字符串表示,故輸出爲5225。

學習進度條

代碼行數(新增/累積) 博客量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一週 120/120 1/1 16/16 開始了JAVA學習的第一步!
第二週 346/466 1/2 23/36 瞭解並學習了Java基礎語法
第三週 364/830 1/3 21/57 進一步瞭解java設計語句
第四周 570/1300 2/5 20/77 初步學習了繼承與多態,接口與多態知識。

嘗試一下記錄「計劃學習時間」和「實際學習時間」,到期末看看能不能改進本身的計劃能力。這個工做學習中很重要,也頗有用。
耗時估計的公式
:Y=X+X/N ,Y=X-X/N,訓練次數多了,X、Y就接近了。

參考:軟件工程軟件的估計爲何這麼難軟件工程 估計方法

參考資料

相關文章
相關標籤/搜索