20145304 Java第四周学习报告

20145304《Java程序设计》第四周学习总结

教材学习内容总结

1.继承共同行为:

  • 继承基本上就是避免多个类间重复定义共同行为,关键词为extends。

代码如下:

//继承共同行为
package cc.openhome;
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;
    }
}
//剑士类
    package cc.openhome;
public class SwordsMan extends Role {
    public void fight(){
        System.out.println("挥剑攻击");
    }
}
//魔法
package cc.openhome;
public class Magician extends Role {
    public void fight() {
        System.out.println("魔法攻击");
    }
    public void cure(){
        System.out.println("魔法攻击");
    }
}

结果截图:

2.多态与is-a:

  • 子类只能继承一个父类。
  • 检查语法的逻辑是否正确时,方式是从=号右边往左读,判断右边是不是左边的子类,若是,则语法正确,若不是,则不正确。
  • 加上Cast语法,可强制使右边成为左边的子类,但有风险。

程序如下:

//第二个主程序
    package cc.openhome;
public class RPG1 {
    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());
    }
}


结果截图:

3.重新定义行为:

  • 在继承父类之后,定义与父类中相同的方法部署,但执行内容不同,这称为重新定义。
  • 防止因打错字而使程序无法运行,可在重新定义某方法时,加上@Override。

代码如下:

)
//继承共同行为
package cc.openhome;
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;
    }
    public void fight(){
        //子类要重新定义fight()的实际行为
    }
}

//P167
    package cc.openhome;
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);

        drawFight(swordsMan);
        drawFight(magician);
    }
    static void drawFight(Role role){
        System.out.print(role.getName());
        role.fight();
    }
}

结果截图:

4.抽象方法、抽象类:

  • 如果某方法区块中真的没有任何程序代码操作,可以使用abstract标示该方法为抽象方法,该方法不用撰写{}区块,直接“;”结束即可。
  • 类中若有方法没有操作,并且表示为abstract,表示这个类定义不完整,定义不完整的类不能生成实例。
  • Java中规定内含抽象方法的类,一定要在class前标示abstract,表示这是一个不完整的抽象类。
  • 子类如果继承抽象类,对于抽象方法有两种做法:一是做法是继续标示该方法为abstract,该子类也是个抽象类,必须在class前标示abstract;二是操作抽象方法。

代码如下:

//继承共同行为
package cc.openhome;
public abstract 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;
    }
    public abstract void fight();
}


5.继承语法细节:

  • 被声明为protected的成员,相同包中的类可以直接存取,不同包中的类可以在继承后的子类直接存取。
  • 依权限小至大来区分,就是private、无关键字、protected与public。
  • 重新定义方法要注意,对于父类中的方法权限,这能扩大但不能缩小。
  • 取得父类方法中的定义,可以在调用方法前,加上super关键词。
  • this()与super()只能择一调用,而且一定要在构造函数第一行执行。
  • final关键词,在定义类时,表示这个类是最后一个了,不能被继承;定义方法时,表示子类不可以重新定义final方法。
  • 任何类型,都可以用Object声明的名称来参考。
  • ArrayList类,可以不限长度地收集对象。
  • 如果定义类时没有使用extends关键字指向任何类,那一定是继承java.lang.Object。
  • 在Java中,任何类追溯至最上层父类,一定就是java.lang.Object。

代码如下:

package cc.openhome;
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());

        }
    }
}

结果截图:

6.垃圾收集:

  • 对于不再有用的对象, JVM有垃圾收集机制,收集到的垃圾对象所占据的内存空间,会被垃圾收集器释放。

7.接口:

  • 接口可以用于定义行为但不能操作,直接标示为abstract,而且一定是public。
  • 类要操作接口,必须使用关键词implements关键字。
  • 操作某接口时,对接口中定义的方法有两种处理方式:一是操作接口中定义的方法,二是再度将该方法标示为abstract。
  • 判断语法是否正确时,看“=”号右边是不是拥有左边的行为,或右边对象是不是操作了左边接口(也可使用Cast语法)。
  • 接口可以继承父接口行为,再在子接口中额外定义行为。

代码如下:

package cc.openhome;
public interface Swimmer {
    public abstract void swim();
}
package cc.openhome;
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();
}

package cc.openhome;
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);
    }
}

package cc.openhome;
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);
    }
}
package cc.openhome;

public class Ocean {
    public static void main(String[] args) {
        doSwim(new Human("贾斯丁"));
        doSwim(new Submarine("黄色一号"));
    }
    static void doSwim(Swimmer swimmer){
        swimmer.swim();
    }
}

结果截图:

8.接口语法细节:

  • 在Java中,可使用interface来定义抽象的行为与外观。接口中的方法没有操作时,一定是公开且抽象的,也可省略,编译程序会自动帮你加上public abstract。
  • 接口中枚举的常数,一定要使用“=”指定值。
  • 如果有临时继承某个类或操作某个接口并建立实例的需求,而这子类或接口操作类只使用一次,不需要为这些类定义名称,这时可以使用匿名内部类似来解决这个需求。
  • enum语法,可用于定义枚举常数。

代码如下:

package cc.openhome;
public class Client{
    public final String ip;
    public final String name;
    public Client(String ip,String name){
        this.ip=ip;
        this.name=name;
    }
}
package cc.openhome;
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;
    }
}
package cc.openhome;
public interface ClientListener{
    void clientAdded(ClientEvent event);
    void clientRemoved(ClientEvent event);
}
package cc.openhome;
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) listeners.get(i);
            listener.clientAdded(event);
        }
    }
    public void remove(Client client){
        clients.remove(client);
        ClientEvent event=new ClientEvent(client);
        for(int i=0;i<listeners.size();i++){
            ClientListener listener=(ClientListener) listeners.get(i);
            listener.clientRemoved(event);
        }
    }
}
package cc.openhome;
public class MultiChat{
    public static void main(String[] args){
        Client c1=new Client("127.0.0.1","Caterpillar");
        Client c2=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.getName(),event.getIp());
            }
            @Override
            public void clientRemoved(ClientEvent event){
                System.out.printf("%s cong %s tuoji%n",
                        event.getName(),event.getIp());
            }
        });
        queue.add(c1);
        queue.add(c2);
        queue.remove(c1);
        queue.remove(c1);
    }
}

结果截图:

教材学习中的问题和解决过程

  • 书上P170页对于子类继承抽象类的两种做法不是很理解。解决方法:希望在之后的学习中可以看到相关的代码帮助理解。

代码调试中的问题和解决过程

  • 1.在调试第一个代码时,无法成功,出现如图所示情况:
    查看原因,应是没有将文件放在同一个包下,只是放在了同一个文件夹,所以无法调用同一个包的东西,通这个例子,还解决了之前的一个疑惑,为何package cc.openhome下会有红线,因为没有放到包文件夹下。

  • 2.在编写接口时,出现如下图错误:

  • 3.在运行代码时,出现以下问题:

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

学习Java已经四周了,很明显的感觉到了Java的优势,继承与多态、接口与多态这些内容,使用户使用时更加方便,也便于编程人员维护。但对于书上一些内容,我理解不够透彻,似懂非懂,还需多多看书,多多敲代码。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 15篇 400小时
第一周 30/30 1/2 20/20
第二周 50/80 1/3 10/30
第三周 130/210 1/4 30/60
第四周 300/510 1/5 30/90

代码托管截图:

参考资料

posted @ 2016-03-27 20:02  20145304刘钦令  阅读(253)  评论(5编辑  收藏  举报