20145216 《Java程序设计》第4周学习总结
教材学习内容总结
第六章 继承与多态
6.1 何谓继承
- 继承基本上就是避免多个类间重复定义共同行为。
- 在Java中,继承时使用extends关键字,private成员也会被继承,只不过子类无法直接存取,必须通过父类提供的方法来存取(如果父类愿意提供访问方法的话)。如:
public class SwordsMan extends Role { public void fight() { System.out.println("挥剑攻击"); } }
- 继承范例:
public class RPG1 { public static void main(String[] args) { demoSwordsMan1(); demoMagician1(); } static void demoSwordsMan1() { SwordsMan1 swordsMan1 = new SwordsMan1(); swordsMan1.setName("Justin"); swordsMan1.setLevel(1); swordsMan1.setBlood(200); System.out.printf("剑士:(%s,%d,%d)%n",swordsMan1.getName(),swordsMan1.getLevel(),swordsMan1.getBlood()); } static void demoMagician1() { Magician1 magician1 = new Magician1(); magician1.setName("Monica"); magician1.setLevel(1); magician1.setBlood(100); System.out.printf("魔法师:(%s,%d,%d)%n",magician1.getName(),magician1.getLevel(),magician1.getBlood()); } }
- 继承的好处:若你要将name、level、blood改为其他名称,那就只要修改Role.java就可以了,只要是继承Role的子类都无须修改。
- 在Java中,子类只能继承一个父类,继承有个重要的关系,就是子类与父类间会有is-a的关系,中文称为“是一种”的关系。
- 检查多态语法逻辑是否正确,方式是从=右边往左读;右边是不是一种左边呢(右边类型是不是左边类型的子类)?如果不是就会编译失败,如果加上扮演(Cast)语法,编译程序就让程序代码通过编译,不过后果得自行负责,也就是扮演失败,执行时会抛出ClassCastException。
- 多态就是使用单一接口操作多种类型的对象。
- 在继承父类之后,定义与父类中相同的方法部署,但执行内容不同,这称为重新定义。如:
父类:
public class Role3
{
...
public void fight()
{
//子类要重新定义fight的实际行为
}
}
子类:
public class SwordsMan3 extends Role3
{
public void fight()
{
System.out.println("挥剑攻击");
}
}
- 如果在子类中某个方法前标注@Override,表示要求编译程序检查,该方法是不是真的重新定义了父类中某个方法,如果不是的话,就会引发编译错误。
- 如果某方法区块中真的没有任何程序中代码操作,可以使用abstract标示该方法为抽象方法,该方法不用撰写{}区块,直接“;”结束即可。
- 子类如果继承抽象类,对于抽象方法有两种做法: 一种做法是继续标示该方法为abstract;另一种做法就是操作抽象方法。
6.2 继承语法细节
- 被声明为protected的成员,相同包中的类可以直接存取,不同包中的类可以在继承后的子类直接存取。如:
父类:
public abstract class Role5
{
protected String name;
protected int level;
protected int blood;
...略
}
子类:
public class SwordsMan5 extends Role5
{
...
public String toString()
{
return String.format("剑士 (%s,%d,%d",this.name,this.level,this.blood);
}
}
- Java中有public、protected与private三个权限关键字,但实际上有四个权限范围:
- 在Java中,如果想取得父类中的方法定义,可以在调用方法前,加上super关键字。如:
public class SwordsMan6 extends Role6 { ... @Override public String toString() { return "剑士" + super.toString(); } }
- 重新定义方法要注意,对于父类中的方法权限,只能扩大但不能缩小。
- 如果子类构造函数中没有指定执行父类中哪个函数,默认会调用父类中无参数构造函数。
- this()与super()只选择一调用,而且一定要在构造函数第一行执行。
- 如果class前使用了final关键字定义,那么表示这个类是最后一个了,不会再有子类,也就是不能被继承。定义方法时,也可以限定该方法为final,这表示最后一次定义方法了,也就是子类不可以重新定义final方法。
- 在Java中,子类只能继承一个父类,如果定义类时没有使用extends关键字指定继承任何类,那一定是继承java.lang.Object。
第七章 接口与多态
7.1 何谓接口
- 对于“定义行为”,在Java中可以使用interface关键字定义。如:
public interface Swimmer1 { public abstract void swim(); }
- 接口可以用于定义行为但不定义操作。
- 类要操作接口,必须使用implements关键字。操作某接口时,对接口中定义的方法有两种处理方式:一是操作接口中定义的方法;二是再度将该方法标示为abstract。如:(第二种方法)
public abstract class Fish1 implements Swimmer1 { protected String name; public Fish1(String name) { this.name = name; } public String getName() { return name; } @Override public abstract void swim(); }
- 以Java的语意来说,继承会有“是一种”关系,操作接口则表示“拥有行为”,但不会有“是一种”的关系。
- 在Java中,类可以操作两个以上的类,也就是拥有两种以上的行为。如:
public class Seaplane3 implements Swimmer1,Flyer3 { private String name; public Seaplane3(String name) { this.name = name; } @Override { System.out.printf("海上飞机 %s 在飞%n",name); } @Override public void swim() { System.out.printf("海上飞机 %s 航行海绵%n",name); } }
- 在Java中,类可以同事继承某个类,并操作某些接口。如:
public class FlyingFish3 extends Fish1 implements Flyer3 { public FlyingFish3(String name) { super(name); } @Override public void swim() { System.out.println("飞鱼游泳"); } @Override public void fly() { System.out.println("飞鱼会飞"); } }
- 在Java中,接口可以继承自另一个接口,也就是继承父接口行为,再在子接口中额外定义行为。如:
父类:
public class Boat4 implements Swimmer1
{
protected String name;
public Boat4(String name)
{
this.name = name;
}
@Override
public void swim()
{
System.out.printf("船在水面 %s 航行%n", name);
}
}
子类:
public class Submarine4 extends Boat4 implements Diver4
{
public Submarine4(String name)
{
super(name);
}
@Override
public void dive()
{
System.out.printf("潜水艇 %s 潜行%n",name);
}
}
7.2 接口语法细节
- 在Java中,可使用interface来定义抽象的行为与外观,如接口中的方法可声明为public abstract。
- 接口中的方法没有操作时,一定得是公开且抽象。
- 在接口中枚举常数,一定要使用=指定值。并且接口枚举常数一定是public static final。
- 接口可以继承别的接口,也可以同时继承两个以上的接口,同样也是使用extends关键字,这代表了继承父接口的行为。
- 如果有临时继承某个类或操作某个接口并建立实例的需求,而这类子类或接口操作类只使用一次,不需要为这些类定义名称,这是可以使用匿名内部类来解决这个需求。匿名内部类的语法为:
new 父类()|接口(){ //类本体操作 };
- enum实际上定义了类,而enum中枚举的常数,实际上是public static final,且为枚举类型实例,无法撰写程序直接实例化枚举类型,因为构造函数权限设定为private,只要类中才可以实例化。如:
import static java.lang.System.out; public class EnumGame { public static void main(String[] args) { play(EnumAction.RIGHT); play(EnumAction.UP); } public static void play(EnumAction 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; } } }
教材学习中的问题和解决过程
问题:
在结合教材、视频和老师博客中的学习指导学习了第六、七章后,发现对于老师给出的思考题——接口与抽象类的区别还是不太清楚。
解决过程:
通过上网百度,我终于弄明白了接口与抽象类的区别,以下是我根据查找的资料总结的二者区别:
- 语法层面上的区别
1、抽象类可以提供成员方法的实现细节,而接口中只能存在public abstract方法; 2、抽象类中的成员变量可以是各种类型的,而接口中的成员变量只能是public static final类型的; 3、一个类只能继承一个抽象类,而一个类却可以实现多个接口。
- 设计层面上的区别
1、抽象类是对一种事物的抽象,即对类抽象,而接口是对行为的抽象;抽象类是对整个类整体进行抽象,包括属 性、行为,但是接口却是对类局部(行为)进行抽象。 2、对于抽象类,如果需要添加新的方法,可以直接在抽象类中添加具体的实现,子类可以不进行变更;而对于接 口则不行,如果接口进行了变更,则所有实现这个接口的类都必须进行相应的改动。
代码调试中的问题和解决过程
问题:
由于教材中的很多范例代码的类名都相同,于是我在类名后编上了号,结果自己敲完代码后出现如图所示错误:
解决过程:
经过反复查看错误代码,我发现该代码中的声明类型(Role)没有与父类的类名(Role1)保持一致,于是我做了以下修改:
最后运行得到正确结果:
总结:
给类名编号后虽然解决了类名重复的问题,但是在敲代码时特别容易出错,因为很多程序代码都是相关联的,必须始终保持创建时的类名和引用时的名称一致,所以在敲代码时一定要细心,并且要先弄懂每行代码的含义,这样才能尽量避免代码中的错误。
本周代码托管截图
其他(感悟、思考等,可选)
本周主要学习了继承与接口的相关知识点,虽然内容较多,对我来说也有一定难度,但是经过对教材的反复研读与琢磨,还是可以慢慢理解和掌握的,当然我也有过因为理解不了代码的含义而烦躁的时候,也想过直接按照书上的代码敲,放弃理解不懂的内容,但是静下心来,还是决定要好好学这门课,其实教材的讲解很详细,代码实例也都与我们所熟悉的内容相关,比如第六章是游戏中的角色,第七章是开发一个海洋乐园游戏,还有类图以及其他的图片解释,这些都方便了我的理解,所以,尽管在学习Java的过程中有许多困难,但是只要自己不放弃就能一一解决问题。
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 4500行 | 30篇 | 350小时 | 能将java运用自如 |
第一周 | 150/150 | 2/2 | 15/15 | 学习了与java相关的基础知识 |
第二周 | 200/350 | 1/3 | 20/35 |
学习了java的基本语法 |
第三周 | 450/800 | 1/4 | 25/60 |
学习了对象和封装的相关知识 |
第四周 | 687/ 1487 | 1/5 | 30/90 |
学习了继承与接口的相关知识 |
参考资料
时间: 2024-10-10 18:19:42