20145236 《Java程序设计》第4周学习总结
教材学习内容总结
第六章 继承与多态
一、继承
•继承是java面向对象编程技术的一块基石,因为它允许创建分等级层次的类。继承可以理解为一个对象从另一个对象获取属性的过程。
•如果类A是类B的父类,而类B是类C的父类,我们也称C是A的子类,类C是从类A继承而来的。在Java中,类的继承是单一继承,也就是说,一个子类只能拥有一个父类
继承中最常使用的两个关键字是extends和implements,这两个关键字的使用决定了一个对象和另一个对象是否是IS-A(是一个)关系。通过使用这两个关键字,我们能实现一个对象获取另一个对象的属性。
•所有Java的类均是由java.lang.Object类继承而来的,所以Object是所有类的祖先类,而除了Object外,所有类必须有一个父类。
•继承的出现提高了代码的复用性。
•继承的出现让类与类之间产生了关系,提供了多态的前提。
继承的特点
1.Java只支持单继承,不支持多继承。
•一个类只能有一个父类,不可以有多个父类。
•class SubDemo extends Demo{} //ok
•class SubDemo extends Demo1,Demo2...//error
2.Java支持多层继承(继承体系)。
•class A{}
•class B extends A{}
•class C extends B{}
3.定义继承需要注意:
•不要仅为了获取其他类中某个功能而去继承
•类与类之间要有所属( " is a " )关系,xx1是xx2的一种。
is—a 关系
使用关键字extends表示is—a关系:
public class Animal{
}
public class Mammal extends Animal{
}
public class Reptile extends Animal{
}
public class Dog extends Mammal{
}
•通过以上例子可以看出:
Animal类是Mammal类的父类。
Animal类是Reptile类的父类。
Mammal类和Reptile类是Animal类的子类。
Dog类既是Mammal类的子类又是Animal类的子类。
•基于以上例子可以看出它们的is—a关系:
Mammal IS-A Animal
Reptile IS-A Animal
Dog IS-A Mammal
Dog IS-A Animal
super关键字
•super和this的用法相同
•this代表本类应用
•super代表父类引用
•当子父类出现同名成员时,可以用super进行区分
•子类要调用父类构造函数时,可以使用super语句。
final关键字
•final可以修饰类,方法,变量。
•final修饰的类不可以被继承。
•final修饰的方法不可以被覆盖。
•final修饰的变量是一个常量。只能被赋值一次。
•内部类只能访问被final修饰的局部变量。
接口
•格式:
interface {}
•接口中的成员修饰符是固定的。
成员常量:public static final
成员函数:public abstract
•接口的出现将“多继承”通过另一种形式体现出来,即“多实现”。
•一般继承基本类和抽象类用extends关键字,实现接口类的继承用implements关键字。
•接口的特点:
1.接口是对外暴露的规则。
2.接口是程序的功能扩展。
3.接口可以用来多实现。
4.类与接口之间是实现关系,而且类可以 继承一个类的同时实现多个接口。
5.接口与接口之间可以有继承关系。
二、多态
•定义:某一类事物的多种存在形态。
•例:动物中猫,狗。
•猫这个对象对应的类型是猫类型
猫x = new 猫();
```
•同时猫也是动物中的一种,也可以把猫称为 动物。
动物y = new 猫();
动物是猫和狗具体事物中抽取出来的父类型。
父类型引用指向了子类对象。
•体现:
父类或者接口的引用指向或者接收自己的子类对象。
•作用:
多态的存在提高了程序的扩展性和后期可维护性。
•前提:
需要存在继承或者实现关系;
要有覆盖操作。
接下来让我们通过实例来了解Java的多态。
public interface Vegetarian{}
public class Animal{}
public class Deer extends Animal implements Vegetarian{}
因为Deer类具有多重继承,所以它具有多态性:
一个 Deer IS-A(是一个) Animal
一个 Deer IS-A(是一个) Vegetarian
一个 Deer IS-A(是一个) Deer
一个 Deer IS-A(是一个)Object
在Java中,所有的对象都具有多态性,因为任何对象都能通过IS-A测试的类型和Object类。
访问一个对象的唯一方法就是通过引用型变量。
引用型变量只能有一种类型,一旦被声明,引用型变量的类型就不能被改变了。
引用型变量不仅能够被重置为其他对象,前提是这些对象没有被声明为final,还可以引用和它类型相同的或者相兼容的对象,它可以声明为类类型或者接口类型。
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("Monica");
magician.setLevel(1);
magician.setBlood(100);
showBlood(swordsMan);//SwordsMan是一种Role
showBlood(magician);//magician是一种Role
}
static void showBlood(Role role){//声明为Role类型
System.out.printf("%s 血量 %d%n",role.getName(),role.getBlood());
}
}
多态以抽象讲法解释,就是使用单一接口操作多种类型的对象,若用以上范例来理解,在showBlood()方法中,既可以通过Role类型操作SwordsMan对象,也可以通过Role类型操作Magician对象。
## 抽象类
Java中可以定义没有方法体的方法,该方法的具体实现由子类完成,该方法称为抽象方法,包含抽象方法的类就是抽象类。
抽象类的特点:
```
1.抽象类和抽象方法必须用abstract关键字来修饰。
2.抽象方法只有方法声明,没有方法体,定义在抽象类中。
格式:修饰符abstract 返回值类型函数名(参数列表) ;
3.抽象类不可以被实例化,也就是不可以用new创建对象。原因如下:
•抽象类是具体事物抽取出来的,本身是不具体的,没有对应的实例。例如:犬科是一个抽象的概念,真正存在的是狼和狗。
•而且抽象类即使创建了对象,调用抽象方法也没有意义。
4.抽象类通过其子类实例化,而子类需要覆盖掉抽象类中所有的抽象 方法后才可以创建对象,否则该子类也是抽象类。
以下是关于抽象类的范例:
import java.util.Scanner;
public class Guess
{
public static void main(String[] args)
{
Scanner scanner = new Scanner (System.in);
int number = (int) (Math.random() * 10);
int guess;
do
{
System.out.printf("猜数字(0—9):");
guess = scanner.nextInt();
}
while(guess != number);
System.out.println("猜中了");
}
}
三、关于垃圾回收(GC)
创建对象会占据内存,如果程序执行流程中已无法再使用某个对象,该对象就只是徒耗内存的垃圾。对于不再有用的对象,JVM有垃圾收集(Garbage Collection,GC)机制,收集到的垃圾对象所占据的内存空间,会被垃圾收集器释放。执行流程中,无法通过变量参考的对象,就是GC认定的垃圾对象。
第七章 接口与多态
一、接口
•格式:
interface {}
•接口中的成员修饰符是固定的。
成员常量:public static final
成员函数:public abstract
•接口的出现将“多继承”通过另一种形式体现出来,即“多实现”。
•一般继承基本类和抽象类用extends关键字,实现接口类的继承用implements关键字。
•接口的特点:
1.接口是对外暴露的规则。
2.接口是程序的功能扩展。
3.接口可以用来多实现。
4.类与接口之间是实现关系,而且类可以 继承一个类的同时实现多个接口。
5.接口与接口之间可以有继承关系。
类要操作接口,必须使用implements关键字。eg:
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();
}
操作某接口时,对接口中定义的方法有两种处理方式,一是操作接口中定义的方法,二是再度将该方法标示为abstract。
二、接口语法细节
接口的默认
•在Java中,可使用interface来定义抽象的行为与外观,如接口中的方法可声明为public abstract。eg:
public interface Swimmer{
public abstract void swim();
}
•接口中的方法没有操作时,一定得是公开且抽象,为了方便,也可以省略public abstract:
public interface Swimmer{
void swim(); //默认就是public abstract
•在interface中,可以定义常数。eg:
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;
}
匿名内部类
•前提:
内部类可以继承或实现一个外部类或者接口。
•语法为:
new 父类()|接口(){ //类文本操作
};
简单理解:
就是建立一个建立一个带内容的外部类或者接口的子类匿名对象。
使用enum枚举常数
先来看一下范例。eg:
public enum Action{
STOP,RIGHT,LEFT,UP,DOWN
}
enum定义了特殊的类,继承自java.lang.Enum,不过这是由编译程序处理,直接撰写程序继承Enum类会被编译程序拒绝。enum实际上定义了类,而enum中列举的常数,实际上是public static final,且为枚举类型实例,无法撰写程序直接实例化枚举类型,因为构造函数权限设定为private,只有类中才可以实现实例化。
教材学习中的问题和解决过程
这两章的内容真的很抽象,我还是像往常一样先看了视频然后又看书,但是感觉还是不能理解这两章的内容,比如到底何为“继承”,脑海里有个抽象的概念就是:面向对象中,子类继承父类,避免重复的行为定义,不过并非为了避免重复定义行为就是用继承。虽然很抽象,但是通过书上给出的例子,研究了一下大概还是可以弄清楚怎么叫继承。其次,检查多态语法逻辑是否正确,方式是从=号右边往左读:右边类型是不是左边类型的子类?如果不是就会编译失败,如果加上扮演(cast)语法,编译程序就让程序代码通过编译。然而,我并不能懂Role类型到底是干嘛的,感觉程序里面出现的频率很高,但我不太会用。这两章内容学起来比较吃力,但是还是离不开敲代码,代码多敲几遍,自己找问题,发现问题,解决问题,勉强还是能理解的。
代码调试中的问题和解决过程
package cc.openhome.RPG;
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("Monica");
magician.setLevel(1);
magician.setBlood(100);
showBlood(swordsMan);//SwordsMan是一种Role
showBlood(magician);//magician是一种Role
}
static void showBlood(Role role){//声明为Role类型
System.out.printf("%s 血量 %d%n",role.getName(),role.getBlood());
}
}
运行结果:
这个程序是书上的程序,程序本身没有问题,但是却运行不了,我不知道是哪里的问题,我猜想可能是新建项目上出了问题。所以目前还没有解决,而且这样的问题遇到过好几次了,我也一直在努力的寻找解决这个问题的办法。
本周代码托管截图
其他(感悟、思考等,可选)
随着课程的推进,我发现越来越难懂,越来越抽象了,有时候感觉自己的问题很多,但是却不知道如何提问题,就感觉有好多东西琢磨不透,学起来有点儿吃力,虽然自己在努力的想要解决问题,但是发现有时候自己找不到问题的根本是什么,有时候实在想不明白就想放弃了,就想反正书上那样写,自己就按照书上写的那样做呗,知道什么类用在什么地方就OK了,但是发现越这样反而遇到的问题越多,总之就是各种迷茫,因为虽然这两章的程序并没有太复杂的,但是每个程序里面的关键词什么的根本不知道它们的含义、用处和区别,书上知识简单的介绍了一下,我想更深的是想要我们自己去理解和体会。有时候自己发现的、总结出来的,远远要比书上或者别人直接告诉你来得深刻和透彻。我觉得每周在我接触《Java程序设计》新的内容的时候我刚开始都挺排斥的,感觉扫一眼自己脑子都大了一样,但是我发现每次自己咬着牙坚持看下去的时候发现其实自己能够充实好多,刚开始接触Java的时候只是觉得编程是一门枯燥的活儿,但是随着经验能力不断地积累,编程遇到困难的时候自己对克服困难,挑战困难的决心也越来越大。我觉得学习了Java不仅增长了自己编程方面的机能,同时也在不断地磨练我的意志!
学习进度条
代码行数(新增/累积) | 博客量(新增/累积) | 学习时间(新增/累积) | 重要成长 | |
---|---|---|---|---|
目标 | 5000行 | 30篇 | 400小时 | |
第一周 | 200/200 | 2/2 | 20/20 | |
第二周 | 300/500 | 2/4 | 18/38 | |
第三周 | 500/1000 | 1/5 | 22/60 | |
第四周 | 500/1500 | 1/6 | 30/90 |