20155208徐子涵 2016-2017-2 《Java程序设计》第4周学习总结
教材学习内容总结
第六章 继承与多态
继承
继承作为面向对象的第二大特征,基本上就是避免多个类间重复定义共同行为。即当多个类中存在相同属性和行为时,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承单独的那个类即可。从而简化了程序,并且减少了冲突错误。 在Java中,通过extends关键字让类与类之间产生继承关系。子类可以直接访问父类中的非私有的属性和行为,而对于private成员也会被继承,只不过子类无法直接存取,必须通过父类提供的方法来存取 继承的特点:继承的出现提高了代码的复用性,也让类与类之间产生了关系,提供了多态的前提。
在Java中,继承时使用extends关键字,private成员也会被继承,只不过子类无法直接存取,必须通过父类提供的方法来存取(如果父类愿意提供访问方法的话)。如下面这个例子:
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的关系,中文称为“是一种”的关系。
多态
- 多态从字面上的解释就是某一类事物的多种存在形态,以抽象讲法解释就是使用单一接口操作多种类型的对象。父类或者接口的引用指向或者接收自己的子类对象,这便是多态的体现,多态的存在提高了程序的扩展性和后期可维护性,但是多态也需要有前提条件,首先,需要存在继承或者实现关系,其次还要有覆盖操作。面向对象的三大特征可以这么来描述:封装是继承的基础,继承是多态的基础。
- 多态就是使用单一接口操作多种类型的对象。
- 在继承父类之后,定义与父类中相同的方法部署,但执行内容不同,这称为重新定义。如:
父类:
public class Role3
{
...
public void fight()
{
//子类要重新定义fight的实际行为
}
}
子类:
public class SwordsMan3 extends Role3
{
public void fight()
{
System.out.println("挥剑攻击");
}
}
如果某方法区块中真的没有任何程序中代码操作,可以使用abstract标示该方法为抽象方法,该方法不用撰写{}区块,直接“;”结束即可。
子类如果继承抽象类,对于抽象方法有两种做法: 一种做法是继续标示该方法为abstract;另一种做法就是操作抽象方法。
继承语法细节
protected成员:被声明为protected的成员,相同包中的类可以直接存取,不同包中的类可以在继承后的子类直接存取。例如下面的例子:假如只想让子类可以直接存取name、level、与blood,就可以定义他们为protected。
如果想取得父类中的方法定义,可以在调用方法前,加上super关键字,重新定义的时候要注意,对于父类中的方法权限,只能扩大不能缩小。如果想执行父类中某构造函数,可以使用super()指定,但要注意的是,this()和super()只能选择其中之一调用,并且一定要在构造函数第一行执行。 如果class前使用了final关键字定义,那么表示这个类是最后一个,不会再有子类,即不能被继承。如果定义类时没有使用extends关键字指定继承任何类,那一定是继承java.lang.Object,在Java中,最上层的父类就是java.lang.Object。
在Java中,如果想取得父类中的方法定义,可以在调用方法前,加上super关键字。如:
public class SwordsMan6 extends Role6
{
...
@Override
public String toString()
{
return "剑士" + super.toString();
}
}
- 在Java中,子类只能继承一个父类,如果定义类时没有使用extends关键字指定继承任何类,那一定是继承java.lang.Object。
第七章 接口与多态
接口
- 对于“定义行为”,可以使用interface关键字定义,接口中的方法不能操作,直接表示为abstract,而且一定是public。类要操作接口,必须使用implements关键字。操作某接口时,对接口中定义的方法有两种处理方式,一是操作接口中定义的方法,二是再度将该方法标示为abstract 操作接口会有“拥有行为”关系,而继承是“是一种”的关系,对于接口多态语法的判断,方式是“右边是不是拥有左边的行为”,或者“右边对象是不是操作了左边接口”。 类可以操作两个以上的类,可以同时继承某个类,并操作某些接口,接口的出现将“多继承”通过另一种形式体现出来,即“多实现”。
- 类要操作接口,必须使用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中,类可以操作两个以上的类,也就是拥有两种以上的行为。如:
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("飞鱼会飞");
}
}
接口语法细节
- 使用interface来定义抽象的行为外观,方法要声明为public abstract,无须且不能有操作。为了方便,也可以省略public abstract,编译程序会协助补齐。可以使用接口枚举常数,只能定义为public static final。为了方便,也可以省略public static final。 接口可以继承别的接口,也可以同时继承两个以上的接口,也是使用extends关键字。 enum语法可用于定义枚举常数,enum实际上定义了类,而enum中列举的常数实际上是public static final,无法撰写程序直接实例化枚举类型,因为构造函数权限设定为private,只有类中才可以实例化。
- 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;
}
}
}
代码调试中的问题和解决过程
问题: 运行代码时出现下面这一问题
解决方法: 发现没有对Scanner这一变量进行定义,import之后成功运行。
其他(感悟、思考等,可选)
我慢慢的感觉学习Java已经变成了每天的一项日常,会不知不觉的在空闲的时候学习一会Java,慢慢的也体会到了Java的乐趣,我相信我会带着这种乐趣一直坚持下去。
学习进度条
代码行数(新增/积累) | 博客量(新增/积累 | 学习时间(新增/累积) | |
---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 |
第一周 | 16/16 | 1/1 | 8/8 |
第二周 | 120/120 | 2/2 | 12/12 |
第三周 | 130/150 | 1/1 | 9/9 |
第四周 | 180/200 | 1/1 | 15/15 |