20145317彭垚 《Java程序设计》第4周学习总结

20145317彭垚 《Java程序设计》第4周学习总结

教材学习内容总结

继承

继承就是避免多个类间重复定义共同行为。

面向对象中,子类继承父类,就是把程序中相同的代码部分提升为父类。

Role.java

package ch6;
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;
    }

}

SwordaMan.java

package ch6;
public class SwordsMan extends Role
{
    public void fight()
    {
        System.out.println("剑士攻击");
    }
}

extends关键字,表示前者会扩充后者的行为,即继承后者的行为。fight()为SwordsMan扩充的Role没有的行为。

Magician.java

package ch6;
public class Magician extends Role
{
    public void fight()
    {
        System.out.println("魔法攻击");
    }
    public void cure()
    {
        System.out.println("魔法治疗");
    }
}

RPG.java

package ch6;
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());

    }
}

private成员也会被继承,不过子类无法直接存取,必须通过父类提供的方法存取。

is-a(是一种)关系

子类只能继承一个父类,这种子类父类之间的关系就是is-a关系

检查语法逻辑是否正确,方式是从=右边往左读:判断右边是不是一种左边。例:Role role1=new SwordsMan();即判断SwordsMan是不是一种Role?若是则语法正确,反之则编译失败。

强制让后者是一种前者:Role role1=new SwordsMan();SwordsMan swordsman=(SwordsMan) role1;

多态

使用单一接口操作多种类型的对象,具有更高的可维护性。

Java以继承及界面来实现多态,是次态多态的一种实现。

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("Moinca");
        magician.setLevel(1);
        magician.setBlood(100);

        showBlood(swordsMan);   //SwordsMan是一种Role
        showBlood(magician);
    }
    static void showBlood(Role role)   //声明为Role类型
    {
        System.out.printf("%s 血量 %d%n",role.getName(), role.getBlood());
    }
}

重新定义行为

SwordsMan与Magician的fight()方法签署的都是public void fight(),操作接口相同,只是方法操作内容不同,因此,可以将fight()方法提升至Role类中定义。

Role.java

public class Role{
    ...
    public void fight()
    {
        //子类要重新定义fight()行为
    }
}

SwordsMan.javaMagician.java都与上例相同。

RPG.java

public class RPG
{
    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("Moinca");
        magician.setLevel(1);
        magician.setBlood(100);

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

如果传入drawFight()的是SwordsMan,role参数参考的就是SwordsMan实例,操作的就是SwordsMan上的fight()方法定义。

重新定义父类中某个方法时,子类必须撰写与父类方法中相同的签署。可以在子类中某个方法前使用@Override要求编译程序检查该方法是不是真的重新定义了父类中某个方法,如果不是会引发编译错误。

对于父类中的方法权限,只能扩大不能缩小。

Role2.java

public abstract class Role2{

    ......
    public String toString(){
        return String.format("(%s, %d, %d)", this.name, this.level, this.blood);
    }
}

SwordsMan2.java

public class SwordsMan2 extends Role2
{
    ......
    @Override
    public String toString(){
        return "剑士"+super.toString();
    }
}

Magician2.java

public class Magician2 extends Role2
{
    ......
    @Override
    public String toString(){
        return "魔法师"+super.toString();
    }
}

如果想执行父类中的某构造函数,可以用super()指定。

抽象方法 抽象类

抽象方法:某方法区块中没有任何程序代码操作,用abstract表示该方法为抽象方法,不用撰写{}区块,直接";"结束即可。

抽象类:内含抽象方法的类,一定要在class前标示abstract,表示类定义不完整,不能用来生成实例。

Role.java

    public abstract class Role{
        ...
        public abstract void fight();
    }

子类继承抽象类方法:1.继续标示该方法为abstract;2.操作抽象方法。

用设计模式设计猜数字程序

GuessGame.java

    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();
    }

ConsoleGame.java

    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();
        }
    }

Guess.java

    public class Guess {
        public static void main(String[] args){
            GuessGame game=new ConsoleGame();
            game.go();
        }
    }

 

protected

被声明为protected的成员,相同包中的类可以直接存取,不同包中的类可以在继承后的子类直接存取。

Role.java

public abstract class Role{

    protected String name;
    protected int level;
    protected int blood;
......
}

SwordsMan.java

public class SwordsMan extends Role
{
    ......
    public String toString(){
        return String.format("剑士(&s, %d, %d)", this.name, this.level, this.blood);
    }
}

Magician.java

public class Magician extends Role
{
    ......
    public String toString(){
        return String.format("魔法师(&s, %d, %d)", this.name, this.level, this.blood);
    }
}
private、无关键字、protected、public权限依次递增。

构造函数

类有继承关系时,会先进行父类定义的初始流程,再进行子类定义的初始流程。

父类中可以重载多个构造函数,如果子类构造函数中没有制定执行父类中哪个构造函数,默认会调用父类中无参数构造函数。

this()super()只能择一调用,并且要写在构造函数第一行执行。

final关键字

class或方法被声明为final,表示这是最后一个,不会再有子类或子类不可以重新定义方法。

java.lang.Object

java.lang.Object是最上层父类,Java中所有对象一定是一种Object。

ArrayList.java不限长度收集对象

    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;
        }
    }

Guest.java收集访客名称并转为大写显示

    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());
            }
        }
    }

 

垃圾收集

JVM有垃圾收集(GC)机制,执行流程中无法通过变量参考的对象就是垃圾对象。GC在进行回收前会调用对象的finalize()方法

接口定义行为

类要操作接口,必须使用implements关键字。操作某接口时,对接口中的定义的方法有两种处理方式,一是操作接口中定义的方法,二是再度将该方法标示为abstract。例如:

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();
}

对于“定义行为”可以使用interface关键字定义,接口中的方法不能操作,直接标示为abstract,而且一定是public
类可以操作两个以上的类,也就是拥有两个以上的行为。类可以同时继承某个类,并操作某些接口,接口可以继承自另一个接口,也就是继承父接口行为,再在子接口中额外定义行为。

接口语法细节

使用interface来定义抽象的行为外观,方法要声明为public abstract,无须且不能有操作。为了方便,也可以省略public abstract,编译程序会协助补齐。可以使用接口枚举常数,只能定义为public static final,为了方便,也可以省略public static final

接口可以继承别的接口,也可以同时继承两个以上的接口,也是使用extends关键字。

enum语法可用于定义枚举常数,enum实际上定义了类,而enum中列举的常数实际上是public static final,无法撰写程序直接实例化枚举类型,因为构造函数权限设定为private,只有类中才可以实例化。

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

这周学习任务很多,课本上的知识也很难一下子全部消化吸收。敲代码真的是一种学习语言的好方式,不但锻炼了自己学习语言的能力,还对课本内容有了深入的理解,我要继续坚持做下去。

学习进度条

 代码行数(新增/累积)博客量(新增/累积)学习时间(新增/累积)重要成长
目标 4000行 24篇 350小时  
第一周 200/200 2/2 20/20  
第二周 200/400 1/3 15/35  
第三周 100/500 2/5 30/65  
第四周 300/800 1/6 20/85  

 

参考资料

Java学习笔记(第8版)

《Java学习笔记(第8版)》学习指导

...

posted @ 2016-03-27 16:13  20145317彭垚  阅读(160)  评论(1编辑  收藏  举报