20145306 学号 《Java程序设计》第4周学习总结
教材学习内容总结
第六章学习总结 继承与多态 继承避免多个类之间的重复定义。可以把相同部分的代码提升为父类。课本上用Role类来作为Swordsman和Magician的父类。在Java中,子类只能继承一个父
类,子类与父类之间存在is-a(是一种)的关系。如Swordsman继承了Role,所以就说Swordsman是一种Role。在编译程序是按照=的右边是不是一种左边来判断
语法逻辑是否正确。若右边不一定是一种左边,可以让右边扮演(Cast)一种左边:Swordsman swordsman =(Swordsman)role;就可以通过编译了。上面这行
代码在执行的时候并不会出错,应为之前 Role role = new Swordsman();的代码让role 参考至Swordsman,所以让swordsman扮演wordsman没有问题。但
Role role = new magician();Swordsman swordsman =(Swordsman) role;会通过编译但执行的时候会有错误。应为role已经参考至Magician,所以
Swordsman不能参考Magician。如果要调用Swordsman和Magician里的get.blood()方法来显示血量,可以分别的重载这两个方法:
public static void showblood(Swordsman swordsman){
System.out.printf("%s血量:%d",swordsman.getnam(),swordsman.getblood()); }
public static void showblood(Magician magician){
System.out.printf("%s血量:%d",magician.getnam(),magician.getblood()); }
但如果需要重载的方法过多的话,显然上面的方法就不适用了。应为Swordsman和Magician类都是继承Role类。所以可以设计如下方法来调用:
public class PRG {
public static void main(String[] args) {
Swordsman swordsman = new Swordsman();
swordsman.setName("Justin");
swordsman.setLeve(1);
swordsman.setBlood(200);
Magician magician = new Magician();
magician.setName("Monica");
magician.setLeve(1);
magician.setBlood(100);
showBlood(swordsman); showBlood(magician); } static void showBlood(Role role) { System.out.printf("%s血量%d",role.getName(),role.getBlood());
}
}
这样的话只要他们继承了Role类就可以使用showBlood()方法来显示血量。 多态以抽象的方法解释就是使用单一的接口操作多种类型的对象。 重新定义行为 在继承父类之后,定义与父类相同的方法部署,但执行的内容不同,成为重新定义(Override)。
public class Magician extends Role {
@Override
public void fight () { System.out.printf("魔法攻击"); } ...
}
抽象方法,抽象类 若某方法区块中没有任何程序代码操作,可以使用abstract表示该方法为抽象方法,给方法不用 {}区块,直接用;结束即可。 Java中规定含有抽象方法的类一定要在class的前面标注abstract。表示定义一个不完整的抽象类。如果尝试用抽象类创建实例会引发编译错误。子类如果继
承抽象类对于抽象方法有两种做法:继续标注该方法为abstract(子类因此也是抽象类);另一种 是操作抽象方法。如果两个都没有做就会引发编译错误。 protected成员 被申明为protected的成员相同包中的类可以直接存取,不同包中的类可以在继承后的子类直接存取。 Java中有public,private,protected,三个权限关键字,但实际上有四个权限范围。
重新定义的细节 对于父类中的方法权限,只能扩大不能缩小。若原来的成员为public,子类中定义时不可以定义为private或者protected。如果想取的父类中的方法定义,可
以在调用方法前加上 super 关键字。 再看构造函数 创建子类实例后,会先执行父类父类构造函数定义的流程,在执行子类构造函数的流程。构造函数可以重载。父类中可以重载多个构造函数。如果子类构造函
数中没有指明执行父类中哪个构造函数,默认调用父类中无参数的构造函数。执行父类中的莫构造函数可以使用super()指定:
class Some {
some(){
System.out.println("调用some"); } soem(int i){
System.out.println("调用some(int i)"); }
}
class Other {
Other(){
super(10);
System.out.println("调用Other");
}
}
final关键字 如果对象数据成员被申明为final,但没有使用=制定只,表示延迟对像成员值的指定,在构造函数执行流程中,一定要对该数据成员指定值,否则会编译错误。
如果class前面使用了final关键字定义,那么表示这个类是最后一个了不会再有子类了,也就是不能被继承了。
第七章接口与多态
接口定义行为
“定义行为”,在java中可以使用interface关键字定义。接口可以用于定义行为但不定义操作。书上例子中,swim()方法用abstract来标识,而且一定用
public来标识,对象若想拥有一个行为,就必须操作包含该行为的接口。类在操作接口时使用implements关键字,操作某接口时,对接口中定义的方法有两种处
理方式,一是操作接口中定义的方法,二是再度将该方法标示为abstract。在Java中,继承会有“是一种”的关系,操作接口则表示“拥有行为”。
行为的多态 判断是否符合语法用“右边是不是拥有左边的行为”可以用扮演语法来让代码通过编译: Swimmer swimmer1=new Shark(); Shark shark=(Shark)
swimmer;执行的时候,因为确实swimmer也是参考Shark实例,所以可以顺利执行。但这种情况:Swimmer swimmer1=new Human();Shark shark=(Shark)
swimmer;虽然可以通过编译,但在程序执行的时候会出现错误。
解决需求变化 如果增加新的需求,原有的程序无须修改,只需针对新需求撰写程序,那就是有弹性,有可维护性的程序。在java中,类可以操作两个以上的类,也就是拥有
两种以上的行为。当然需求是无止境的,原有程序框架也许确实可满足某些需求,但有些需求也可能超过了原有架构预留的弹性,一开始要如何设计才会有弹性
,则必须靠经验和分析判断。课本上的例子:如果要增加一个新的行为fly,就要定义一个新的接口:
public interface Flyer{
public abstract void fly();
}
public class seaplane implements Swimmer,Flyer {
....
@Override
public void fly(){
System.out.println("海上飞机%s在飞%n",name);
}
@Override
public void swim(){
System.out.println("海上飞机%s航行海面%n",name);
}
接口的默认
在java中,可使用interface来定义抽象的行为与外观,如接口中的方法可声明为public abstract。如:public interface Swimmer{ public abstract
void swim();} 接口中的方法没有操作时,一定得是公开且抽象,为了方便,你也可以省略public abstract,编译程序会自动帮你加上public abstract。
interface Action {
void execute();//编译程序会自动加上public abstract;
}
class some implements Action {
void execute () {
System.out.println(“做一些服务”);
}
public class main{
public static void main(String[] args) {
Action action = new some();
action.execute(); }
}
上面的程序不能通过编译,Action中定义的execute()方法默认用public abstract 标识,而some类在操作接口是没有 申明public因此是包权限。这等于
把Action里的execute方法缩小的权限,所以编译不通过。
Java中经常见到在接口中定义这类常数,称为枚举常数。撰写程序的时候可以省略public static final,系统会自动帮你写上public static final,所以
在接口中枚举常数,一定要使用=指定值,否则就会编译错误。 类可以操作两个以上的接口,如果有两个接口都定义了某方法,而操作两个接口的类会怎样?程序面上来说,并不会有错误,照样通过编译。
interface Some{
void execute();
void doSome();
} interface Other{
void execute ();
void doOther ();
}
public class Service implements Some,Other {
@Override
public void execute (){
System.out.println("execute()");
}
@Override
public void doSome (){
System.out.println("doSome ()");
}
@Override
public void doOther (){
System.out.println("doOther ()");
}
}
但还是要思考一下,如果表示不同的行为,那么在操作时,应该有不同的方法操作,some与other的execute()方法在名称上就得不同。如果表示相同的行
为,那可以定义一个父接口,在当中定义execute()方法,而some与other继承该接口,各自定义自己的doSome()与doOther()方法。接口使用extends可
以同时继承两个以上的接口.这代表了继承父接口的行为
其他(感悟、思考等,可选)
xxx学习两章的内容花了挺长的时间,也有了很大的收获。在学习一些抽象的概念时联系具体的事例会有助于加深理解。 xxx