20145219 《Java程序设计》第04周学习总结
2016-03-26 15:51
351 查看
20145219 《Java程序设计》第04周学习总结
教材学习内容总结
继承继承就是避免多个类间重复定义共同行为。
面向对象中,子类继承父类,就是把程序中相同的代码部分提升为父类。
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.java和Magician.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关键字。
操作接口时,对接口中定义的方法有两种处理方式:1.操作接口中定义的方法2.再度将该方法标示为abstract。
Java的接口支持多重继承,操作接口表示“拥有行为”,但不是“是一种”的关系。
Swimmer.java
public interface Swimmer { public abstract void swim(); }
Fish.java
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(); }
Human.java
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); } }
Submarine.java
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); } }
Ocean.java
public class Ocean{ public static void main(String[] args) { doSwim(new Human("贾斯汀")); doSwim(new Submarine("黄色一号")); } static void doSwim(Swimmer swimmer){ swimmer.swim(); } }
解决需求变化
增加新的需求,原有的程序无需修改,只需针对新需求撰写程序,就是有弹性、具可维护性的程序。
Java中类可以操作两种以上的类。
Flyer.java
public interface Flyer { public abstract void fly(); }
Airplane.java
public class Airplane implements Swimmer,Flyer{ private String name; public Airplane(String name){ this.name=name; } public String getName() { return name; } @Override public void fly(){ System.out.printf("海上飞机 %s 在飞%n",name); } @Override public void swim(){ System.out.printf("海上飞机 %s 航行海面%n",name); } }
FlyingFish.java
public class FlyingFish extends Fish implements Flyer{ public FlyingFish(String name){ super(name); } @Override public void swim(){ System.out.println("飞鱼游泳"); } @Override public void fly(){ System.out.println("飞鱼会飞"); } }
Ocean2.java
public class Ocean2{ public static void main(String[] args) { doSwim(new Human("贾斯汀")); doSwim(new Submarine("黄色一号")); doSwim(new Airplane("空军零号")); doSwim(new FlyingFish("甚平")); } static void doSwim(Swimmer swimmer){ swimmer.swim(); } }
接口的默认
Java中可以使用interface来定义抽象的行为和外观。
接口中的方法没有操作时一定得是公开且抽象的。
接口可以继承别的接口,也可以同时继承两个以上的接口,同样也是用extends关键字,这代表了继承父接口的行为。
枚举常数
使用接口
Action.java
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; }
Game.java
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("不支持此动作"); } } }
使用enum:enum定义了特殊的类,继承自java.lang.Enum,由编译程序处理。
Action2.java
public enum Action2 { STOP,RIGHT,LEFT,UP,DOWN }
Game2.java
import static java.lang.System.out; public class Game2{ public static void main(String[] args){ play(Action2.RIGHT); play(Action2.UP); } public static void play(Action2 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; } } }
匿名内部类
临时继承某个类或操作某个接口并建立实例,由于这类子类或接口操作类只使用一次,不需要为这些类定义名称,可以使用匿名内部类。
Client.java
public class Client{ public final String ip; public final String name; public Client(String ip,String name){ this.ip=ip; this.name=name; } }
ClientEvent.java
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; } }
ClientListener.java
public interface ClientListener{ void clientAdded(ClientEvent event); void clientRemoved(ClientEvent event); }
ClientQueue.java
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); } } }
MultiChat.java
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 从 %s 联机%n", event.getName(),event.getIp()); } @Override public void clientRemoved(ClientEvent event){ System.out.printf("%s 从 %s 脱机%n", event.getName(),event.getIp()); } }); queue.add(c1); queue.add(c2); queue.remove(c1); queue.remove(c2); } }
学会使用wc统计代码行数
在power cmd中输入`wc -l *.java
代码调试中的问题和解决过程
问题:本来像书上p167中的fight()方法运行都没有问题,但是按照书上p169抽象方法与抽象类中,将前面的Role.java中的fight()方法改成如下的格式public abstract void fight();之后,RPG.java就运行不了了。
解决方法:待解决。
本周代码托管截图
其他(感悟、思考等,可选)
第6、7章的内容有许多的代码,从这两章中知道了,并不是一个项目中只能建一个class,更多时候要把很多class放在一个包里来一起运行才能达到预期效果。由于前几周最后完成博客时都比较赶,这一周我早早的就开始看书、运行代码、看视频,没有再把任务都拖到最后让自己手忙脚乱,学习还是应该尽量往前赶,不要拖延。学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 150/150 | 1/2 | 15/15 | 学会搭建Java环境,学会写Hello World小程序 |
第二周 | 350/500 | 1/3 | 20/35 | 掌握IDE的使用方法,学会Java的基本语法规则 |
第三周 | 400/900 | 1/4 | 35/70 | 学会代码托管,学习了类类型、面向对象、函数等知识 |
第四周 | 990/1890 | 1/5 | 40/110 | 学会使用wc统计代码行数,学会将多个class文件放在一个包内 |
参考资料
Java学习笔记(第8版)《Java学习笔记(第8版)》学习指导
...
相关文章推荐
- 对java中int与Integer的一些理解
- Java中的抽象类和接口
- Spring的依赖注入
- 管理Java垃圾回收的五个建议
- 错误:java.lang.UnsupportedClassVersionError: Bad version number in .class file
- SVN工具的使用 和在Eclipse中安装GPD插件:(多步审批流,因此选择使用工作流(JBPM)来实现)
- java测试URL是否连通的方法
- 20145218 《Java程序设计》第四周学习总结
- struts的DevMode模式问题
- Java Vector 类
- java中静态代码块的用法 static用法详解
- Java线程总结
- for 循环中植入两个变量
- 转 spring 常用工具类
- Notification的用法
- (转)java.util.ResourceBundle使用详解
- Java笔记---CenOS下配置Mysql
- java二十二节-输入输出总结
- Java中Class类浅谈
- Java学习笔记--ThreadLocal