20155321 2016-2017-2 《Java程序设计》第四周学习总结

20155321 2016-2017-2 《Java程序设计》第四周学习总结

教材学习内容总结

第六、七章 继承 多态 接口 相应的语法细节

继承
  • 关键字 extends

  • 格式 class 子类名 extends 父类名 {}

  • 产生原因:也许许多类(例如老师,学生,工人)具有相同的属性与功能,反复重复代码会让阅读性变得很差,代码也显得也繁杂,为了解决此问题,可以考虑让其中一个类与其他类产生一个关系,让其他类可以直接使用这个类的功能,这个关系就叫做继承

  • 好处:提高代码的复用性,利于维护,使代码阅读性增强,更加简洁

  • 弊端:因为类与类之间产生了关系 (类的耦合性增强了),因为低耦合(类与类的关系),高内聚(自己完成某件 事的能力,尽量自己做),某一个类的改变直接影响了另一个类,也许这个改变另一个类不希望有这个改变

  • 特点:只支持单继承,不支持多继承,但支持多层继承。例如,A可以继承B,B可以继承C,那么A也继承C,但A不能同时继承A和B

  • 注意事项:

    1)子类只能继承父类所有非私有的成员(成员方法和成员变量),对于私有成员要靠父类提供的方法去访问

    2)子类不继承父类的构造方法,但可通过super关键字去访问父类的构造方法

    3)不为了部分功能去继承,有时候可能会多了不想要的功能。继承体现的是一种关系,若有两个类A,B,当他们符合A是B的一种,或者B是A的一种的时候,可以考虑使用继承

  • 继承中成员变量的关系:当子类中的成员变量和父类中的成员变量名称一样,在子类方法中访问一个变量的查找顺序为:在子类方法的局部范围找——在子类的成员范围找——在父类的成员范围找,若还找不到就报错

  • 继承间构造方法的关系

    1)子类中所有的构造方法默认都会访问父类中空参数的构造方法

    2)子类会继承父类中的数据,可能还会使用父类的数据,所以,子类初始化前要先完成父类数据的初始化子类每一个构造方法的第一条语句默认是:super()

  • 继承中构造方法的注意事项

    如果父类没有无参构造方法(自己给了个带参的),那么子类的构造方法会报错。其解决办法有以下三种:第一种,在父类中加一个无参构造方法;第二种,当父类只有带参的话,子类通过super去显示地调用父类其他的带参的构造方法;第三种,子类通过this去调用本类的其他构造方法(但子类中一定要有一个去访问了父类的构造方法,否则父类数据无法初始化)但要注意,this(...)或者super(...)必须出现在第一条语句上,如果不是放在第一条语句上,就可能对父类的数据进行了多次初始化,所以必须放在第一条语句上

  • 继承中成员方法的关系

    1)子类中的方法和父类中的方法声明不一样

    2)子类中的方法和父类中的方法声明一样,通过子类调用方法,其寻找顺序为:先找子类中看看有没有这个方法,有就使用;再看父类中,有没有这个方法,有就使用;如果还没有就报错

  • 关于方法重写(方法覆盖/方法复写):子类中出现了和父类中方法声明一模一样的方法(返回类型,方法名,参数列表),不同类中出现

方法重载 本类中出现的方法名一样,与返回类型无关,参数列表不同

使用特点:如果方法名不同,就调用对应方法;如果方法名相同,就调用子类自己的

方法重写的应用:当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样,既沿袭了父类的功能,又定义了子类特有的内容

注意事项:1)父类中私有方法不能被重写

2)子类重写父类方法时,访问权限不能更低,最好就一致

3)父类静态方法,子类也必须通过静态方法重写

4)子类重写父类方法时候,最好声明一模一样

  • 一个类的初始过程

    1)成员变量初始化-默认初始化-显示初始化-构造方法初始化

    2)静态代码块>构造代码块>构造方法,即静态代码块Fu——静态代码块Zi——构造代码块Fu——构造方法Fu——构造代码块Zi——构造方法Zi

静态的内容是随着类的加载而加载,静态代码块的内容会优先执行

  • this和super(父类引用,父类存储空间的标识,可操作父类的成员)

    调用成员变量:super.成员方法 调用父类的成员变量

    调用构造方法:super(...) 调用父类的构造方法

    调用成员方法:super.成员方法 调用父类的成员方法

注意虽然子类中构造方法默认有一个super(),但初始化的时候,不是按照那个顺序进行的,而是按照分层初始化进行的,它仅仅表示要先初始化父类数据,再初始化子类数据

多态
  • 概念:某一个事物在不同时刻表现出来的不同状态;例如水在不同时刻的状态不同

new的时候从右边往左边读

  • 多态的前提:要有继承关系;要有方法重写;要有父类引用指向子类对象
    父类 f = new 子类();

  • 多态的弊端:不能使用子类的特有功能

    若就是要使用子类的特有功能,进行转型

    向上转型:Fu f = new Zi();

    向下转型:Zi z = (Zi)f;(但要求该f必须是能够转换为Zi的)

  • 继承中的多态中方法的特点:

    1)子类中有和父类中一样的方法,叫重写。

    2)子类中没有父亲中出现过的方法,方法就被继承过来了。

内部类与匿名内部类
  • 成员内部类和局部内部类

成员内部类:定义在成员位置上
局部内部类:定义在局部位置(方法)

  • 内部类的访问规则

    1)内部类的成员可以直接访问外部的成员,包括私有(因为内部类中持有外部类的引用,格式 外部类名.this

    2)外部类要访问内部类,必须建立内部类对象

  • 内部类的访问格式

    1)当内部类定义在外部类的成员位置上,而且非私有,可以在外部其他类中直接建立内部类对象
    格式 外部类名.内部类名 变量名 = 外部类对象.内部类对象

    2)当内部类在成员位置上,就可被成员修饰符所修饰。例如,private可将内部类在外部类中进行封装;static令内部类具备静态特性——只能直接访问外部类中的static成员,即出现了访问局限;但是private可以保证数据的安全性;static可以方便访问数据(可用类名调用)

    3)当内部类中定义了静态成员,该内部类必须是static;当外部类中的静态方法访问内部类时,内部类也必须是static

在外部其他类中,直接访问static内部类的非静态成员的方法:建立对象new 外部类名.内部类名().方法名();

在外部其他类中,直接访问static内部类的静态成员的方法:利用类名调用,外部类名.内部类名.方法名();

局部内部类访问局部变量的注意事项:局部内部类访问局部变量必须用final修饰(原因是局部变量是随着方法的调用而调用,随着调用完毕而消失。但是堆内存的内容并不会立即消失,因此加final修饰,加入final修饰后,这个变量就成了常量)

  • 匿名内部类

    1)匿名内部类本质是内部类的简写格式,是一个继承了该类或者实现了该接口的子类匿名对象

    2)定义匿名内部类的前提:内部类必须继承一个类或者实现接口

    3)匿名内部类的格式:new 父类或者接口() {重写方法}

    4)其实匿名内部类就是一个匿名子类对象。而且这个对象有点胖,可以理解为带内容的对象

    5)匿名内部类中定义的方法最好不超过3个

接口
  • 抽象类和接口的区别

    1)成员区别

    抽象类:成员变量(可以变量,也可以常量),构造方法(有),成员方法(可抽象,也可非抽象)

    接口:成员变量(只能常量),成员方法(只能抽象)

    2)关系区别

    类与类(继承,单继承),类与接口(实现,单实现,多实现),接口与接口(继承,单继承,多继承)

    3)设计理念区别

    抽象类:被继承体现的是”is-a”的关系,抽象类中定义的是该继承体系的共性功能。
    接口:被实现体现的是:like-a的关系,接口中定义的是该继承体系的扩展功能

教材学习中的问题和解决过程

  • 问题1:对public、protected、private之间的区别掌握得不够清楚
  • 解决方案:看了学习指导上的解释

初步总结:

修饰符:权限修饰符、状态修饰符、抽象修饰符

类:
1)权限修饰符:默认修饰符,public

2)状态修饰符:final

3)抽象修饰符:abstra
public修饰用得较多

成员变量:
1)权限修饰福:4种均可

2)状态修饰符:static,final

private用得较多

构造方法:只有权限修饰符:4种均可,用得较多的是public

成员方法:
1)权限修饰符:4种均可

2)状态修饰符:static,final

3)抽象修饰符:abstract
用得较多的是public

目前见到的组合规则:
成员变量:public static final

成员方法:public static、public abstract、public final

  • 问题2:对课本P164中多态的理解不是很明白
  • 解决方案:通过自己不断地尝试,从内存方面进行理解并结合敲代码终于明白了(见下图)

代码调试中的问题和解决过程

  • 问题 对程序的结果不理解

  • 解决方案:后面经过查书发现自己对继承方面理解得不够好,如果子类复写了父类的方法,那么调用子类方法的时候,先找子类的方法

代码托管

上周考试错题总结

  • 错题1:填空:p86 命令行下编译Guess.java的命令是(javac -d . Guess.java)

    原因:一直在IDEA上编,没有输入这些命令,因此忽略了-d . ,直接写了javac Guess.java

    理解情况:注意要把编译好的文件放到对应的文件夹里,因此要用-d,下次要注意

  • 错题2:判断: Java中,=与==并没有在基本类型和类类型的不同(OK)

    原因:对=于==掌握得得比较模糊

    理解情况:对象之间的==符是用来比较是否是一个对象的两个引用(即比较地址是否相同)

  • 错题3:填空:两个Integer对象比较大小,可以使用(compareTo())方法

    原因:以为是equals()方法,对compareTo()与equals()的区别不太理解

    理解情况:equals() 用于引用数据类型比较是否指向相同的对象,compareTo()用于对象的大小

  • 错题4:判断:Java中方法内可以定义类(OK)

    原因:对内部类这部分的知识掌握得不好

    理解情况:方法中不能直接定义方法,但可以在方法中定义类,类里面再定义方法

  • 错题5:填空:“30”转化为byte类型的30的语句是(Byte.parseByte(“30”);)。

    原因:没考虑到要去调用方法,受C语言的影响直接使用了强转

    理解情况:通过查API得知了parseByte的相关参数,但还是有一个疑问,为什么不直接用强转的方法?

  • 错题6:填空: p109 Average.java 求1,2,3,4,5的平均值的命令是(java cc.openhome.Average 1 2 3 4 5)

    原因:对题意理解失误,因为是写输出命令

    理解情况:题目的意思是在命令行下输出什么命令来求1,2,3,4,5的平均值,因此是java cc.openhome.Average 1 2 3 4 5,之后的1,2,3,4,5是用户输入

其他(感悟、思考等,可选)

在本周的学习中,周一我对上周所学的知识进行了一定的复习,并学习了第六章的开头,周二我主要是在看书、看资料进行学习第六章,没有进行敲代码的过程。周三、周四对周二学的代码进行编写,本来以为这些代码比较简单,因为在学习的过程中感觉没遇到太多的困难,但是在真正敲代码的时候,我遇到了许多编译上的错误,包括少了()、缺了public等修饰词等,这些错误都是在我看书的时候所没有发现的,而且我发现对比看书上程序的结果记住一些结论,自己手动编代码去验证书上的结论的效果要差一些。对于第六章的学习,我个人觉得继承与接口中的多态是我此章学习的一个难点,遇到难点时,也应该主动在网上寻找更形象的解释来帮助自己理解,并学会自己手动敲代码去得出结论。

学习进度条

代码行数(新增/累积) 博客量(新增/累积) 学习时间(新增/累积) 重要成长
目标 5000行 30篇 400小时
第一周 1/ 20/20 对IDEA、git、JDK、JVM有了更多的了解,面对学习过程中遇到的困难学会自己主动地寻找办法去解决
第二周 1/2 18/38 掌握了Java中的基本运算符和基本语句
第三周 /1110 1/3 22/60 对面向对象、封装、构造函数等重要知识点有了初步理解,学会自主学习,遇到困难的时候从多方面寻找资料以求答案
第四周 823/1933 1/4 25/85 对继承和多态了一定程度的理解,并学会使用多态来提高代码的复用性

尝试一下记录「计划学习时间」和「实际学习时间」,到期末看看能不能改进自己的计划能力。这个工作学习中很重要,也很有用。
耗时估计的公式
:Y=X+X/N ,Y=X-X/N,训练次数多了,X、Y就接近了。

计划学习时间:20小时
实际学习时间:25小时

参考资料

原文地址:https://www.cnblogs.com/rafell/p/6580156.html