首页 / JAVA / Java学习笔记 第十天
Java学习笔记 第十天
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java学习笔记 第十天,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含10671字,纯文字阅读大概需要16分钟。
内容图文
![Java学习笔记 第十天](/upload/InfoBanner/zyjiaocheng/621/25a5d9a619294dbf86ceb3be8c76adec.jpg)
Java学习笔记 第十天
第一章 继承
1.1 概述:
当多个类中存在相同属性和行为时,可将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那一个类即可。其中,多个类可以称为子类,单独那一个类称为父类、超类(superclass)或者基类。
继承描述的是事物之间的所属关系,这种关系是:的关系。例如,图中兔子属于食草动物,食草动物属于动物。可见,父类更通用,子类更具体。我们通过继承,可以使多种事物之间形成一种关系体系。
继承的定义: 就是子类继承父类的属性和行为,使得子类对象具有与父类相同的属性、相同的行为。子类可以直接访问父类中的非私有的属性和行为。
1.2 继承的格式
通过extends关键字,可以声明一个子类继承另外一个父类,定义格式如下:
class 父类{
...
}
class 子类 extends 父类{
...
}
代码演示如下:
// 定义一个员工:父类
public class Employee {
public void method(){
System.out.println("方法执行!");
}
}
// 定义了一个员工的子类:讲师
public class Teacher extends Employee {
}
// 定义了员工的另一个子类:助教
public class Assistant extends Employee{
}
public class Demo01Extends {
public static void main(String[] args) {
// 创建了一个子类对象
Teacher teacher = new Teacher();
// Teacher类当中虽然什么都没写,但是会继承来自父类的method方法
teacher.method();
// 创建另一个子类助教的对象
Assistant assistant = new Assistant();
// Assistant类当中虽然什么都没写,但是也会继承来自父类的method方法
assistant.method();
}
}
1.3 继承后的特点—成员变量
- 成员变量不重名
如果子类父类中出现不重名的成员变量,这时的访问是没有影响的。代码如下:
// 定义父类
class Fu{
int numFu = 5;
}
// 定义子类
class Zi extends Fu{
int numZi = 10;
public void show(){
// 继承而来且不重名,故可直接访问
System.out.println("父类当中的numFu = " + numFu);
System.out.println("子类当中的numZi = " + numZi);
}
}
// 定义测试类
class ExtendDemo02{
public void main(String[] args){
// 创建子类对象
Zi zi = new Zi();
// 调用子类中的show方法
zi.show();
}
}
演示结果:
父类当中的numFu = 5
子类当中的numZi = 10
- 成员变量重名
如果子类父类中出现重名的成员变量,这时的访问是有影响的(按照就近原则选取成员变量,如果没有就向上查找,而绝不会向下查找)。代码如下:
// 定义父类
class Fu{
int num = 5;
}
// 定义子类
class Zi extends Fu{
int num = 10;
public void show(){
// 此时父类和子类当中都有名为num的成员变量,所以根据就近原则,会输出子类当中的num
System.out.println("父类当中的numFu = " + num);
System.out.println("子类当中的numZi = " + num);
}
}
// 定义测试类
class ExtendDemo02{
public void main(String[] args){
// 创建子类对象
Zi zi = new Zi();
// 调用子类中的show方法
zi.show();
}
}
演示结果:
父类当中的numFu = 10
子类当中的numZi = 10
子父类中出现了同名的成员变量时,在子类中需要访问父类中非私有成员变量时,需要使用super关键字,修饰父类成员变量,类似于之前学过的this。
使用格式:
super.父类成员变量名
对上面的代码进行修改,代码如下:
// 定义父类
class Fu{
int num = 5;
}
// 定义子类
class Zi extends Fu{
int num = 10;
public void show(){
// 使用super关键字选取
System.out.println("父类当中的numFu = " + super.num);
System.out.println("子类当中的numZi = " + num);
}
}
// 定义测试类
class ExtendDemo02{
public void main(String[] args){
// 创建子类对象
Zi zi = new Zi();
// 调用父类中的fuShow方法
zi.fuShow();
zi.ziShow();
}
}
小贴士: Fu类中的成员变量是非私有的,子类中可以直接访问。若Fu类中的成员变量私有了,子类是不能直接访问的。通常编码时,我们遵循封装的原则,使用private修饰成员变量,那么如何访问父类的私有成员变量呢?对!可以在父类中提供公共的getXxx方法和setXxx方法。
1.4 继承后的特点—成员方法
1.4.1 成员方法不重名
如果子类父类中出现不重名的成员方法,这时的调用是没有影响的。对象调用方法时,会先在子类中查找有没有对应的方法,若子类中存在就会执行子类中的方法,若子类中不存在就会执行父类中相应的方法。简单来说就是,访问规则依然按照就近原则访问,且绝对不会向下查找。
代码如下:
// 定义父类
class Fu{
public void fuShow(){
System.out.println("Fu类当中的show方法执行");
}
}
// 定义子类
class Zi extends Fu{
public void ziShow(){
System.out.println("Zi类当中的show方法执行");
}
}
// 定义测试类
public class ExtendsDemo04{
public static void main(String[] args){
Zi zi = new Zi();
// 子类中没有show方法,但是可以找到父类方法去执行
zi.show()
}
}
1.4.2 成员方法重名—方法重写
如果子类父类中出现重名的成员方法,这时的访问是一种特殊情况,叫做方法重写(Override)。
子类中出现与父类一模一样的方法时(返回值类型,方法名和参数列表都相同),会出现覆盖效果,也称为重写或者复写。声明不变,重新实现。
代码如下:
// 定义父类
class Fu{
public void show(){
System.out.println("Fu show");
}
}
// 定义子类
class Zi extends Fu{
// 子类重写了父类的show方法
@Override
public void show(){
System.out.println("Zi show");
}
}
// 定义测试类
public class ExtendsDemo05{
public static void main(String[] args){
Zi zi = new Zi();
// 子类当中有show方法,只执行重写后的show方法
zi.show();
}
}
方法重写的5大注意事项:
-
【1】.必须保证父子类之间的方法名称相同,参数列表也相同。
@Override:写在方法前面,用来检测是不是有效的正确覆盖重写。
这个注解就算不写,只要满足要求,也是正确的方法覆盖重写。但是推荐写上,以防出现错误 -
【2】.子类方法的返回值必须【小于等于】父类方法的返回值范围
详细来说,分以下几种情况:
?1. 父类被重写的方法的返回值类型是void,则子类重写的方法的返回值类型只能是void
?2. 父类被重写的方法的返回值类型是A类型,则子类重写的方法的返回值类型可以是A类或A类的子类(java.lang.Object类是所有类的公共最高父类(祖宗类),java.lang.String就是Object的子类)
?3. 父类被重写的方法的返回值类型是基本数据类型(比如:double),则子类重写的方法的返回值类型必须是相同的基本数据类型(必须也是double)
?4. 父类被重写的方法的返回值类型是基本数据类型(比如:double),则子类重写的方法的返回值类型必须是相同的基本数据类型(必须也是double)
-
【3】.子类方法的权限必须【大于等于】父类方法的权限修饰符
小扩展提示:public > protected > (default) > private
备注:(default)不是关键字default,而是什么都不写,留空 -
【4】.子类重写的方法抛出的异常类型不大于父类被重写的方法抛出的异常类型(具体放到异常处理时候讲)
-
【5】.子类和父类中的同名同参数的方法要么都声明为非static的(考虑重写),要么都声明为static的(不是重写)。
1.4.2 方法重写的应用
子类可以根据需要,定义特定于自己的行为。既沿袭了父类的功能名称,又根据子类的需要重新实现父类方法,从而进行扩展增强。比如新的手机增加来电显示头像的功能,代码如下:
// 定义父类
class Phone{
public void sendMessage(){
System.out.println("发短信");
}
public void call(){
System.out.println("打电话");
}
public void showNum(){
System.out.println("来电显示号码");
}
}
// 定义子类
class NewPhone extends Phone{
// 重写父类的showNum成员方法
@Override
public void showNum){
// 调用父类已有的功能要用super关键字
super.showNum();
System.out.println("显示来电姓名");
System.out.println("显示头像");
}
}
// 定义测试类
public class ExtendsDemo06{
public static void main(String[] args){
// 创建子类对象
NewPhone np = new NewPhone();
// 调用父类继承而来的方法
np.call();
// 调用子类重写的方法
np.showNum();
}
}
注意:
这里在进行重写时,用到super.父类成员方法,表示调用父类的成员方法。
1.5 继承后的特点—构造方法
首先我们要回忆两个事情,构造方法的定义格式和作用。
1.构造方法的名字是与类名一致的。所以子类是无法继承父类构造方法的。
2.构造方法的作用是初始化成员变量的。所以子类的初始化过程中,必须先执行父类的初始化动作。子类的构造方法中默认有一个super(),表示调用父类的构造方法,父类成员变量初始化后,才可以给子类使用。代码如下:
// 定义父类
class Fu{
private int n;
// 定义父类构造方法
public Fu(){
System.out.println("Fu()");
}
}
// 定义子类
class Zi extends Fu{
// 定义子类构造方法
public Zi{
// super() 调用父类构造方法
super();
System.out.println("Zi()");
}
}
// 定义测试类
public class ExtendsDemo07{
public static void main(String[] args){
Zi zi = new Zi();
}
}
输出结果:
Fu()
Zi()
继承关系中父子类构造方法的访问特点
- 子类构造方法当中有一个默认隐含的“super()”调用,所以一定是先调用的父类构造,后执行的子类构造
- 子类构造可以通过super关键字来调用父类重载构造
- super的父类构造调用,必须是子类构造方法的第一个语句。也就是说,不能一个子类构造调用多次super构造
第二章 易混淆概念思考
本人由于之前学过一丁点Python语言,所以在几类变量之间理解与Python当中有所混淆,这里进行区分总结(如有错误,请予以私信、评论等指正)。ps:再次声明,本人只是学生,请以批判的眼光看待所发文章
首先声明,Java当中没有Python当中所谓的全局变量的概念
-
成员变量、this
在类当中,方法外定义的变量是成员变量,类似于Python当中的实例属性,作用域是整个类(即可以在整个类中都被访问到)。
但是不同于Python的是,Python当中访问实例属性,一定是通过self.实例属性来访问。而Java当中通常情况下都可直接访问成员变量,只有在当局部变量和成员变量重名的时候,才会使用和self功能相似的this关键字,用this.成员变量来访问,这里使用this关键字的目的仅仅是用于区分成员变量和局部变量。而this实际上是代表所在类当前对象的内存地址 -
类变量(类属性,static修饰)
在类当中,方法外,用static关键字修饰的变量就是类变量,类变量相当于Python当中的类属性,和Python中的类属性理解相同,类变量作用域和成员变量一样都是整个类,可通过对象名或类名来调用,但是推荐使用类名来调用类变量,以强调这是类变量 -
类方法(静态方法,static修饰)
用static关键字修饰的成员方法就是类方法,和类变量一样,可通过对象名或类名来调用,但是推荐使用类名来调用类方法,以强调这是类方法 -
局部变量
1.形参(形式参数)
作用域:在整个方法内有效
2.方法局部变量 (方法内定义)
从定义这个变量开始到方法结束这一段时间内有效 -
继承和super关键字
当类之间产生了关系以后,如果子类和父类当中的成员变量不重名,则在访问时是没有影响的。但是,当子类和父类当中出现重名的**成员变量(成员方法)**时候,这时的访问是有影响的。此时,在子类当中需要访问父类中非私有成员变量时,需要使用super关键字,修饰父类成员变量,类似于之前学过的this关键字,作用在于区别父类当中的成员变量(成员方法)和子类当中的成员变量(成员方法) -
this和super关键字的详细汇总
this关键字三种用法:
1.当在本类当中成员变量和方法的局部变量相同时,可以用this.成员变量来加以和方法的局部变量进行区分
2.和Python当中一样,在本类的成员方法A中,可以通过用this.成员方法B,来在成员方法A中访问成员方法B
3.在本类的构造方法中,访问本类的另一个构造方法,代码示范如下;
// 定义父类
public class Fu{
int num = 30;
}
public class Zi extends Fu {
int num = 20;
public Zi(){
// super(); // 这一行不再赠送
this(123); // 本类的无参构造,调用本类的有参构造
// this(1,2); // 错误写法
}
public Zi(int n){
this(1,2);
}
public Zi(int n,int m){
}
}
注意:
在上面第三点用this访问另外一个构造方法时候有以下两点考虑:
A.this(…)调用也必须是构造方法的第一个语句,即只能调用唯一一个。
B.super和this两种调用不能同时使用,不能同时使用。
- super关键字三种用法
1.在子类的成员方法中访问父类的成员变量,用以区别变量名相同时的情形
2.在子类的成员方法中访问父类的成员方法,用以区别成员方法名相同时的情形
3.在子类的构造方法中访问父类的构造方法
// 定义父类
public class Fu {
int num = 10;
public void method(){
System.out.println("父类方法");
}
}
// 定义子类
public class Zi extends Fu{
int num = 20;
public Zi(){
super();
}
public void methodZi(){
System.out.println(super.num); // 父类当中的num
}
public void method(){
super.method(); // 访问父类中的method
System.out.println("子类方法");
}
}
内容总结
以上是互联网集市为您收集整理的Java学习笔记 第十天全部内容,希望文章能够帮你解决Java学习笔记 第十天所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。