20145227 《Java程式設計》第4周學習總結

20145227鄢曼君發表於2016-03-26

20145227 《Java程式設計》第4周學習總結

教材學習內容總結

第六章 繼承與多型

6.1 何謂繼承

1、繼承共同行為

  • 多個類中存在相同屬性和行為時,將這些內容抽取到單獨一個類中,那麼多個類無需再定義這些屬性和行為,只要繼承單獨的那個類即可。
  • 多個類可以稱為子類,單獨這個類稱為父類或者超類。
  • 子類可以直接訪問父類中的非私有的屬性和行為。
  • 通過extends 關鍵字讓類與類之間產生繼承關係。
  • 以實際例子來說明繼承。程式碼如下:
public class RPG
{
    public static void main (String[] args)
    {
        demoSwordsMan();
        demoMagician();
    }
    static void demoSwordsMan()
    {
        SwordsMan swordsMan = new SwordsMan();
        swordsMan.setName("Justin");
        swordsMan.setLevel(1);
        swordsMan.setBlood(200);
        System.out.printf("劍士:(%s.%d,%d)%n",swordsMan.getName(),
                swordsMan.getLevel(),swordsMan.getBlood());
    }
    static void demoMagician()
    {
        Magician magician = new Magician();
        magician.setName("Moinca");
        magician.setLevel(1);
        magician.setBlood(100);
        System.out.printf("魔法師:(%s,%d,%d)%n",magician.getName(),
                magician.getLevel(),magician.getBlood());
        
    }
}

public class SwordsMan extends Role
{
    public void fight()
    {
        System.out.println("揮劍攻擊");
    }
}

public class Magician extends Role
{
    public void fight()
    {
        System.out.println("魔法攻擊");
    }

    public void cure()
    {
        System.out.println("魔法治療");
    }   
} 

public class Role{
    private String name;
    private int level;
    private int blood;
    
    public int getBlood()
    {
        return blood;
    }
    public void setBlood(int blood)
    {
        this.blood = blood;
    }
    public int getLevel()
    {
        return level;       
    }
    public void setLevel(int level)
    {
        this.level = level;
    }
    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name = name;
    }

}
  • 結果截圖:
    20145227 《Java程式設計》第4周學習總結

2、多型與is-a

  • Java只支援單繼承,不支援多繼承。一個類只能有一個父類,不可以有多個父類。
  • Java支援多層繼承(繼承體系) 。
  • 定義繼承需要注意:類與類之間要有所屬( " is a " )關係,以前面範例來說,SwordsMan繼承了Role,所以SwordsMan is a Role。
  • 以實際例子來說明多型。程式碼如下:
public class RPG2
{
    public static void main(String[] args)
    {
        SwordsMan swordsMan = new SwordsMan();
        swordsMan.setName("Justin");
        swordsMan.setLevel(1);
        swordsMan.setBlood(200);
        
        Magician magician = new Magician();
        magician.setName("Monica");
        magician.setLevel(1);
        magician.setBlood(100);
        
        showBlood(swordsMan);
        showBlood(magician);
        
    }
    static void showBlood(Role role)
    {
        System.out.printf("%s 血量 %d%n",role.getName(),role.getBlood());
    }
}
  • 結果截圖:

20145227 《Java程式設計》第4周學習總結

3、重新定義行為

  • 在繼承父類之後,定義與父類中相同的方法部署,但執行內容不同,這稱為重新定義。
public class RPG3
{
    public static void main(String[] args)
    {
        SwordsMan3 swordsMan = new SwordsMan3();
        swordsMan.setName("Justin");
        swordsMan.setLevel(1);
        swordsMan.setBlood(200);
        
        Magician magician = new Magician();
        magician.setName("Monica");
        magician.setLevel(1);
        magician.setBlood(100);
        
        drawFight(swordsMan);
        drawFight(magician);
        
    }
    static void drawFight(Role3 role)
    {
        System.out.print(role.getName());
        role.fight();
    }
}

public class Magician extends Role3
{
    public void fight()
    {
        System.out.println("魔法攻擊");
    }

}
public class SwordsMan3 extends Role3
{
    public void fight()
    {
        System.out.println("揮劍攻擊");
    }

}
public class Role3
{

        private String name;
        private int level;
        private int blood;

        public int getBlood()
        {
            return blood;
        }
        public void setBlood(int blood)
        {
            this.blood = blood;
        }
        public int getLevel()
        {
            return level;
        }
        public void setLevel(int level)
        {
            this.level = level;
        }
        public String getName()
        {
            return name;
        }
        public void setName(String name)
        {
            this.name = name;
        }



    public void fight()
    {
        
    }
}
  • 結果截圖
    20145227 《Java程式設計》第4周學習總結

4、抽象方法、抽象類

  • 抽象類:Java中可以定義沒有方法體的方法,該方法的具體實現由子類完成,該方法稱為抽象方法,包含抽象方法的類就是抽象類。 
  • 抽象方法的由來:多個物件都具備相同的功能,但是功能具體內容有所不同,那麼在抽取過程中,只抽取了功能定義,並未抽取功能主體,那麼只有功能宣告,沒有功能主體的方法稱為抽象方法。
  • 抽象類和抽象方法必須用abstract關鍵字來修飾。

6.2 繼承語法細節

1、protected成員

  • 程式碼如下:
public abstract class Role5
{
    protected String name;
    protected int level;
    protected int blood;
    
    public int getBlood()
    {
        return blood;
    }
    public void setBlood(int blood)
    {
        this.blood = blood;
    }
    public int getLevel()
    {
        return level;       
    }
    public void setLevel(int level)
    {
        this.level = level;
    }
    public String getName()
    {
        return name;
    }
    public void setName(String name)
    {
        this.name = name;
    }


}
public class Magician5 extends Role5
{

    public void fight()
    {
        System.out.println("魔法攻擊");
    }
    
    public String toString()
    {
        return String.format("魔法師 (%s, %d, %d)", this.name, this.level, this.blood);
    }
    
}
public class SwordsMan5 extends Role5
{

    public void fight()
    {
        System.out.println("揮劍攻擊");
    }
    public String toString()
    {
        return String.format("劍士 (%s, %d %d)", this.name, this.level, this.blood);
    }
    
}

2、重新定義的細節

  • 對於父類中的方法許可權,只能擴大但不能縮小。若原來成員public,子類中重新定義時不可為private或protected。
  • 程式碼如下:
public abstract class Role6
{
    public String toString()
    {
        return String.format("(%s, %d, %d)", this.name, this.level, this.blood);
    }
}

3、final關鍵字

  • final可以修飾類,方法,變數。 
  • final修飾的類不可以被繼承。final修飾的方法不可以被覆蓋。 
  • final修飾的變數是一個常量,只能被賦值一次。 
  • 內部類只能訪問被final修飾的區域性變數。

4、java.lang.Object

  • 在Java中,子類只能繼承一個父類,如果定義類時沒有使用extends關鍵字指定繼承任何類,那一定是繼承java.lang.Object。
  • 程式碼如下:
import java.util.Arrays;

public class ArrayList {
private Object[] list;
private int next;

public ArrayList(int capacity) {
list=new Object[capacity];
}

public ArrayList() {
this(16);
}

public void add(Object o) {
if(next==list.length) {
list=Arrays.copyOf(list, list.length*2);
}
list[next++]=o;
}
public Object get(int index) {
return list[index];
}

public int size() {
return next;
}
}
import java.util.Scanner;
import static java.lang.System.out;

public class Guest {
public static void main(String[] args) {
ArrayList names=new ArrayList();
collectNameTo(names);
out.println("訪客名單:");
printUpperCase(names);
}

static void collectNameTo(ArrayList names) {
Scanner console=new Scanner(System.in);
while(true) {
out.print("訪客名稱:");
String name=console.nextLine();
if(name.equals("quit")) {
break;
}
names.add(name);
}
}

static void printUpperCase(ArrayList names) {
for(int i=0;i<names.size();i++) {
String name=(String) names.get(i);
out.println(name.toUpperCase());
}
}
}
  • 結果截圖:

20145227 《Java程式設計》第4周學習總結

5、抽象類

  • 程式碼如下:
public abstract class GuessGame {
public void go() {
int number=(int)(Math.random()*10);
int guess;
do {
print("輸入數字:");
guess=nextInt();
}while(guess!=number);
println("猜中了");
}

public void println(String text) {
print(text+"\n");
}

public abstract void print(String text);
public abstract int nextInt();
}
import java.util.Scanner;

public class ConsoleGame extends GuessGame {
private Scanner scanner=new Scanner(System.in);

@Override
public void print(String text) {
System.out.print(text);
}

@Override
public void println(String text) {
System.out.println(text);
}


@Override
public int nextInt() {
return scanner.nextInt();
}
}
public class Guess {
public static void main(String[] args){
GuessGame game=new ConsoleGame();
game.go();
}
}
  • 結果截圖:

20145227 《Java程式設計》第4周學習總結

第七章 介面與多型

7.1 何謂介面

1.介面定義行為

  • 介面的出現將“多繼承”通過另一種形式體現出來,即 “多實現”。
  • 介面是程式的功能擴充套件。 
  • 介面可以用來多實現。 
  • 類與介面之間是實現關係,而且類可以繼承一個類的同時實現多個介面。 
  • 介面與介面之間可以有繼承關係。
  • 程式碼如下:
public class Anemonefish extends Fish{
public Anemonefish(String name){
super(name);
}


@Override
public void swim();{
System.out.printf("小丑魚 %s 游泳%n",name);
}
}
public class Shark extends Fish{
public Shark(String name){
super(name);
}


@Override
public void swim();{
System.out.printf("鯊魚 %s 游泳%n",name);
}
}
public interface Swimmer
{
public abstract void swim();
}
public abstract class Fish implements Swimmer{
protected String name;
public Fish(String name){
this.name=name;
}
public String getName()
{
return name;
}
@Override
public abstract void swim();
}
public class Human implements Swimmer {
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);
}
}
public class Submarine implements Swimmer{
private String name;
public Submarine(String name){
this.name=name;
}
public String getName()
{
return name;
}


@Override
public void swim();{
System.out.printf("潛水艇 %s 潛行%n",name);
}
}

2.行為的多型

  • 程式碼如下:
public class Ocean{
public static void main(String[] args)
{
doSwim(new Anemonsfish("尼莫"));
doSwim(new Shark("蘭尼"));
doSwim(new Human("賈斯汀"));
doSwim(new Submarine("黃色一號"));
}

static void doSwim(Swimmer swimmer){
swimmer.swim();
}
}
  • 結果截圖:

20145227 《Java程式設計》第4周學習總結

3.解決需求變化

  • 寫程式時,如果增加新的需求,可使原有的程式無需修改,只針對新需求撰寫程式。
  • 程式碼如下:
public interface Flyer{
public abstract void fly();
}
public class FlyingFish extends Fish implements Flyer{
public FlyingFish(String name){
super(name);
}


@Override
public void swim(){
Systen.out.println("飛魚游泳");
}



@Override
public void fly(){
Systen.out.println("飛魚會飛");
}
}
public class Airplane implements Flyer{
protected String name;
public Airplane(String name){
this.name=name;
}



@Override
public void fly();{
Systen.out.printf("飛機 %s 在飛%n",name);
}
}
public class Ocean2{
public static void main(String[] args)
{
doSwim(new Seaplane("空軍零號"));
doSwim(new FlyingFish("甚平"));
}

static void doSwim(Swimmer swimmer){
swimmer.swim();
}
}
  • 結果截圖

20145227 《Java程式設計》第4周學習總結

7.2 介面語法細節

1.介面的預設

  • 在java中,可使用interface來定義抽象的行為與外觀,如介面中的方法可宣告為public abstract。
  • 程式碼如下:
public interface Action{
    public static final int STOP=0;
    public static final int RIGHT=1;
    public static final int LEFT=2;
    public static final int UP=3;
    public static final int DOWN=4;
}
import static java.lang.System.out;
public class Game{
    public static void main(String[] args){
        play(Action.RIGHT);
        play(Action.UP);
    }
    public static void play(int action){
        switch(action){
            case Action.STOP:
            out.println("播放停止動畫");
            break;
            case Action.RIGHT:
            out.println("播放向右動畫");
            break;
            case Action.LEFT:
            out.println("播放向左動畫");
            break;
            case Action.UP:
            out.println("播放向上動畫");
            break;
            case Action.DOWN:
            out.println("播放向下動畫");
            break;
            default:
            out.println("不支援此動作");
        }
    }
}
  • 結果截圖
    20145227 《Java程式設計》第4周學習總結

2.匿名內部類:就是內部類的簡化寫法。

  • 前提:內部類可以繼承或實現一個外部類或者介面。 
  • 格式為:new 外部類名或者介面名(){覆蓋類或者介面中的程式碼, ( 也可以自定義內容。)} 
  • 程式碼如下:
public class Client{
    public final String ip;
    public final String name;
    public Client(String ip,String name){
        this.ip=ip;
        this.name=name;
    }
}
public class ClientEvent{
    private Client client;
    public ClientEvent(Client client){
        this.client=client;
    }
    public String getName(){
        return client.name;
    }
    public String getIp(){
        return client.ip;
    }
}
public interface ClientListener{
    void clientAdded(ClientEvent event);
    void clientRemoved(ClientEvent event);
}
import java.util.ArrayList;
public class ClientQueue{
    private ArrayList clients=new ArrayList();
    private ArrayList listeners=new ArrayList();
    public void addClientListener(ClientListener listener){
        listeners.add(listener);
    }
    public void add(Client client){
        clients.add(client);
        ClientEvent event=new ClientEvent(client);
        for(int i=0;i<listeners.size();i++){
            ClientListener listener=(ClientListener) listener.get(i);
            listener.client.Added(event);
        }
    }
    public void remove(Client client){
        client.remove(client);
        ClientEvent event=new ClientEvent(client);
        for(int i=0;i<listeners.size();i++){
            ClientListener listener=(ClientListener) listener.get(i);
            listener.client.Removed(event);
        }
    }
}
public class Multichat{
    public static void main(String[] args){
    Client c1=new Client("127.0.0.1","Caterpillar");
    Client c1=new Client("192.168.0.2","Justin");
    
    ClientQueue queue=new ClientQueue();
    queue.addClientListener(new ClientListener(){
        @Override
        public void clientAdded(ClientEvent event){
            System.out.printf("%s cong %s lianji%n",
            event.getGame(),event.getIp());
        }
        @Override
        public void clientRemoved(ClientEvent event){
            System.out.printf("%s cong %s tuoji%n",
            event.getGame(),event.getIp());
        }
    });
    queue.add(c1);
    queue.add(c2);
    queue.remove(c1);
    queue.remove(c1);
}
}
  • 結果截圖

20145227 《Java程式設計》第4周學習總結

3.使用enum列舉常數

  • 程式碼如下:
public enum Action2{
    STOP,RIGHT,LEFT,UP,DOWN
}
import static java.lang.System.out;
public class Game2{
    public static void main(String[] args){
        play(Action.RIGHT);
        play(Action.UP);
    }
    public static void play(Action action){
        switch(action){
            case STOP:
            out.println("播放停止動畫");
            break;
            case RIGHT:
            out.println("播放向右動畫");
            break;
            case LEFT:
            out.println("播放向左動畫");
            break;
            case UP:
            out.println("播放向上動畫");
            break;
            case DOWN:
            out.println("播放向下動畫");
            break;
        }
    }
}
  • 結果截圖:

20145227 《Java程式設計》第4周學習總結

  • 程式碼託管截圖

20145227 《Java程式設計》第4周學習總結
20145227 《Java程式設計》第4周學習總結
20145227 《Java程式設計》第4周學習總結

20145227 《Java程式設計》第4周學習總結

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

這次的內容對於我來說還是比較困難的,一開始我一直以為Java中每一個專案是相對獨立的,這周通過對繼承和介面的學習才明白,有很多專案彼此之間是有著千絲萬縷的聯絡的,比如設計一個海洋樂園遊戲,就需要很多個小程式碼相互配合才能出現預期的效果。

其他(感悟、思考等,可選)

學習java已經四個星期了,這周學習了java第六章第七章的內容。這周敲了很多書上的程式碼,有些取得了預期的效果,有些卻始終不行,後面通過看視訊以及查閱資料慢慢的解決了一些問題。有一部分依然不能解決。同時,這周我有試著自己脫離課本敲了一些程式碼,雖然是很簡單的,但是看到執行結果出來的那一刻還是很開心。

學習進度條

程式碼行數(新增/累積) 部落格量(新增/累積) 學習時間(新增/累積) 重要成長
目標 5000行 30篇 400小時
第一週 200/200 2/2 20/20
第二週 200/400 1/3 20/40
第三週 500/900 1/4 30/70
第四周 1072/1972 1/5 30/100

參考資料

相關文章