学习笔记,仅供参考


文章目录

  • 面向对象
    • 继承
      • 继承中成员变量的关系
      • this和super的区别
      • 继承中构造方法的关系
      • 继承中构造方法的注意事项
      • 继承中的成员方法关系

面向对象

继承

继承中成员变量的关系

我们看下面这段代码,猜测一下输出内容是啥:

class ExtendsTest2 {public static void main(String[] args) {Son s = new Son();s.print();}
}class Father {int num1 = 10;int num2 = 30;
}class Son extends Father {int num2 = 20;public void print() {System.out.println(num1);System.out.println(num2);}
}

输出:

10
20

可以看到,根据就近原则,print()方法里的num2代表的是子类的成员变量,而不是父类的成员变量。

那么我们怎样才能在print()方法中输出父类的成员变量呢?

下面我们介绍来一下关键字super。

this和super的区别

  • this和super都代表什么

    • this: 代表当前对象的引用,谁来调用我,我就代表谁
    • super: 代表当前对象父类的引用
  • this和super的使用区别
    • 调用成员变量

      • this.成员变量 调用本类的成员变量,也可以调用父类的成员变量
      • super.成员变量 调用父类的成员变量
    • 调用构造方法
      • this(…) 调用本类的构造方法
      • super(…) 调用父类的构造方法
    • 调用成员方法
      • this.成员方法 调用本类的成员方法,也可以调用父类的方法
      • super.成员方法 调用父类的成员方法
  • 举个例子
class ExtendsTest2 {public static void main(String[] args) {Son s = new Son();s.print();}
}class Father {int num1 = 10;int num2 = 30;
}class Son extends Father {int num2 = 20;public void print() {System.out.println(this.num1);  //父类num1(如果本类没有该成员变量,就调用父类的)System.out.println(this.num2);  //本类num2(如果本类有该成员变量,就调用本类的)System.out.println(super.num2); //父类num2(直接调用父类的成员变量)}
}

输出:

10
20
30

继承中构造方法的关系

子类中所有的构造方法默认都会访问父类中空参数的构造方法,因为子类会继承父类中的数据,可能还会使用父类的数据。所以,子类初始化之前,一定要先完成父类数据的初始化。

  • 举个例子
class Demo5_Extends {public static void main(String[] args) {Son s = new Son();}
}class Father {public Father() {System.out.println("Father 的构造方法");}
}class Son extends Father {public Son() {System.out.println("Son 的构造方法");}
}

输出:

Father 的构造方法
Son 的构造方法

我们看到,当我们创建Son类的对象时,它不仅会调用本类的空参构造方法,而且会自动调用父类的空参构造方法,且JAVA先执行父类的构造方法,再执行子类的构造方法。

对于每一个类来说,在初始化本类之前,都会先初始化父类。

那么Father类的父类是谁呢?

是Object类。Object类是最顶层的类,对于所有类来说,Object类直接或间接的是它们的父类,如果一个类没有人为的继承任何其他类,那么它的直接父类就是Object类。

上面的代码也可以写成:

class Demo5_Extends {public static void main(String[] args) {Son s = new Son();}
}class Father extends Object {  //public Father() {super();System.out.println("Father 的构造方法");}
}class Son extends Father {public Son() {super();   //先执行父类的构造方法,再执行子类的构造方法System.out.println("Son 的构造方法");}
}

输出:

Father 的构造方法
Son 的构造方法

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

  • 父类中没有无参构造方法,子类该怎么办?

我们首先看一段代码:

class Demo5_Extends {public static void main(String[] args) {Son s1 = new Son();System.out.println("--------");Son s2 = new Son("Huang", 9);}
}class Father {String name;int age;public Father() {System.out.println("Father空参构造方法");}public Father(String name, int age) {this.name = name;this.age = age;System.out.println("Father有参构造方法," + name + ":" + age);}
}class Son extends Father {public Son() {System.out.println("Son空参构造方法");}public Son(String name, int age) {this.name = name;this.age = age;System.out.println("Son有参构造方法," + name + ":" + age);}
}

输出:

Father空参构造方法
Son空参构造方法
--------
Father空参构造方法
Son有参构造方法,Huang:9

我们看到,不管我们走Son的空参还是有参构造方法,都会执行Father的空参构造方法。

那么如果父类中没有空参构造方法,会发生什么事情呢?

我们把上面代码中Father类的空参构造去掉:

class Demo5_Extends {public static void main(String[] args) {Son s1 = new Son();System.out.println("--------");Son s2 = new Son("Huang", 9);}
}class Father {String name;int age;public Father(String name, int age) {this.name = name;this.age = age;System.out.println("Father有参构造方法," + name + ":" + age);}
}class Son extends Father {public Son() {System.out.println("Son空参构造方法");}public Son(String name, int age) {this.name = name;this.age = age;System.out.println("Son有参构造方法," + name + ":" + age);}
}

报错:

---------- javac ----------
Demo5_Extends.java:23: 错误: 无法将类 Father中的构造器 Father应用到给定类型;public Son() {^需要: String,int找到: 没有参数原因: 实际参数列表和形式参数列表长度不同
Demo5_Extends.java:27: 错误: 无法将类 Father中的构造器 Father应用到给定类型;public Son(String name, int age) {^需要: String,int找到: 没有参数原因: 实际参数列表和形式参数列表长度不同
2 个错误Output completed (4 sec consumed) - Normal Termination

可以看到,报错了!这是因为我们的父类中只有有参构造方法,没有空参构造方法,而这段代码中,Son的构造方法调用的是父类的空参构造方法。

那现在该咋整呢?

  • 通过super解决

首先改Son的有参构造:

class Demo5_Extends {public static void main(String[] args) {//Son s1 = new Son();//System.out.println("--------");Son s2 = new Son("Huang", 9);}
}class Father {String name;int age;public Father(String name, int age) {this.name = name;this.age = age;System.out.println("Father有参构造方法," + name + ":" + age);}
}class Son extends Father {public Son(String name, int age) {super(name, age);this.name = name;this.age = age;System.out.println("Son有参构造方法," + name + ":" + age);}
}

输出:

Father有参构造方法,Huang:9
Son有参构造方法,Huang:9

很好,没有报错!

再改Son的空参构造:

class Demo5_Extends {public static void main(String[] args) {Son s1 = new Son();//System.out.println("--------");//Son s2 = new Son("Huang", 9);}
}class Father {String name;int age;public Father(String name, int age) {this.name = name;this.age = age;System.out.println("Father有参构造方法," + name + ":" + age);}
}class Son extends Father {public Son() {super("Bai", 10);System.out.println("Son空参构造方法");}
}

输出:

Father有参构造方法,Bai:10
Son空参构造方法

可以看到,这样改代码虽然没有报错,但是我们在空参构造时,就把name和age定死了。

  • 利用this解决

我们看下面这段代码:

class Demo5_Extends {public static void main(String[] args) {Son s1 = new Son();System.out.println("--------");Son s2 = new Son("Huang", 9);}
}class Father {String name;int age;public Father(String name, int age) {this.name = name;this.age = age;System.out.println("Father有参构造方法," + name + ":" + age);}
}class Son extends Father {public Son() {this("Bai", 10);    //本类的构造方法System.out.println("Son空参构造方法");}public Son(String name, int age) {super(name, age);  //父类的构造方法this.name = name;this.age = age;System.out.println("Son有参构造方法," + name + ":" + age);}}

输出:

Father有参构造方法,Bai:10
Son有参构造方法,Bai:10
Son空参构造方法
--------
Father有参构造方法,Huang:9
Son有参构造方法,Huang:9

我们可以通过在Son的空参构造方法中设置this("Bai", 10);指向Son的有参构造,来解决父类中没有空参构造的问题。

同时,我们需要注意的是,super()和this()都必须是构造器中的第一条语句,所以如果我们想使用,就只能使用super()和this()中的一个。

比如,如果我们同时使用super()和this()则会报错:

class Demo5_Extends {public static void main(String[] args) {Son s1 = new Son();//System.out.println("--------");//Son s2 = new Son("Huang", 9);}
}class Father {String name;int age;public Father(String name, int age) {this.name = name;this.age = age;System.out.println("Father有参构造方法," + name + ":" + age);}
}class Son extends Father {public Son() {super("Tim", 6);this("Bai", 10);System.out.println("Son空参构造方法");}public Son(String name, int age) {super(name, age);this.name = name;this.age = age;System.out.println("Son有参构造方法," + name + ":" + age);}}

报错:

---------- javac ----------
Demo5_Extends.java:25: 错误: 对this的调用必须是构造器中的第一个语句this("Bai", 10);^
1 个错误Output completed (2 sec consumed) - Normal Termination

继承中的成员方法关系

当父类中存在子类没有的方法,而我们通过子类的对象去调用该方法时,会执行父类的方法:

class Demo7_Extends {public static void main(String[] args) {Son s = new Son();s.print();s.method();}
}class Father {public void print() {System.out.println("Father print");}
}class Son extends Father {public void method() {System.out.println("Son Method");}}

输出:

Father print
Son Method

但当子类有与父类重名的方法时,我们再通过子类的对象去调用该方法时,就会执行子类的方法:

class Demo7_Extends {public static void main(String[] args) {Son s = new Son();s.print();s.method();}
}class Father {public void print() {System.out.println("Father print");}
}class Son extends Father {public void method() {System.out.println("Son Method");}public void print() {System.out.println("Son print");}}

输出:

Son print
Son Method

那如果在子类有与父类重名的方法时,我想调用父类的方法,该咋整呢?

我们可以用super.方法名()去调用:

class Demo7_Extends {public static void main(String[] args) {Son s = new Son();s.print();s.method();}
}class Father {public void print() {System.out.println("Father print");}
}class Son extends Father {public void method() {System.out.println("Son Method");}public void print() {super.print();}}

输出:

Father print
Son Method

第三次学JAVA再学不好就吃翔(part31)--super关键字相关推荐

  1. 第三次学JAVA再学不好就吃翔(part107)--字符流的拷贝

    学习笔记,仅供参考,有错必纠 文章目录 IO流 字符流的拷贝 拷贝纯文本文件 注意事项 自定义字符数组的拷贝 IO流 字符流的拷贝 拷贝纯文本文件 zzz.txt: 安徽财经大学 JAVA代码: pa ...

  2. 第三次学JAVA再学不好就吃翔(part30)--继承

    学习笔记,仅供参考 文章目录 面向对象 继承 先来个例子 继承的好处和弊端 Java中类的继承特点 继承的注意事项 面向对象 继承 继承(extends),让类与类之间产生关系,比如子父类关系. 先来 ...

  3. 第三次学JAVA再学不好就吃翔(part106)--字符流

    学习笔记,仅供参考,有错必纠 文章目录 IO流 字符流输入流FileReader 字符流是什么 FileReader类构造方法 举个例子 字符流输出流FileWriter FileWriter构造方法 ...

  4. 第三次学JAVA再学不好就吃翔(part46)--Scanner类

    学习笔记,仅供参考 文章目录 Scanner类 Scanner获取数据出现的问题 Scanner类 概述 Scanner是在java.util包下的一个类,使用该类时我们需要导包.这个类被final修 ...

  5. 第三次学JAVA再学不好就吃翔(part117)--单例设计模式

    学习笔记,仅供参考,有错必纠 文章目录 多线程 单例设计模式 饿汉式 懒汉式 第三种格式 Timer类 线程的五种状态 多线程 单例设计模式 单例设计模式,即保证类在内存中只有一个对象,如何保证类在内 ...

  6. 第三次学JAVA再学不好就吃翔(part109)--LineNumberReader类

    学习笔记,仅供参考,有错必纠 IO流 LineNumberReader类 该类继承自java.io.BufferedReader,该类可以跟踪行号的缓冲字符输入流.此类定义了方法 setLineNum ...

  7. 第三次学JAVA再学不好就吃翔(part108)--带缓冲的字符流

    学习笔记,仅供参考,有错必纠 文章目录 IO流 带缓冲的字符流 BufferedReader和BufferedWriter readLine和newLine方法 IO流 带缓冲的字符流 Buffere ...

  8. 第三次学JAVA再学不好就吃翔(part7)--基础语法之运算符

    学习笔记,仅供参考 文章目录 JAVA基础语法 运算符 算数运算符 算术运算符 ++和-- 赋值运算符 关系运算符 JAVA基础语法 运算符 什么是运算符 就是对常量和变量进行操作的符号. 运算符的分 ...

  9. 第三次学JAVA再学不好就吃翔(part115)--多线程

    学习笔记,仅供参考,有错必纠 文章目录 多线程 多线程引入 什么是线程 多线程并行和并发的区别 Java程序运行原理 多线程的实现方式 多线程实现的方式1 多线程程序实现的方式2 以上两种实现方式的区 ...

最新文章

  1. 报错-Unknown class in Interface Builder file
  2. 静态程序分析chapter2 - IR(Jimple) 和 CFG
  3. 使用weka进行Cross-validation实验
  4. 计算机自动启动无法开机,为何插上电源 电脑会自动开机 但是又开不起来
  5. axure 调整中继器列宽_在Axure中用“中继器”实现对表格的增、删、改
  6. 如何在 vue-cli v3.0 中使用 SCSS/SASS
  7. 浙大计算机专硕培养方案,浙江大学硕士研究生培养方案
  8. 5专题总结-数据结构
  9. C语言递归算法(一)
  10. Python字典中 get() 函数的使用
  11. HTTP2.0,HTTP1.1,HTTP1.0三者在通性性能上的优化方法
  12. 计算机组成原理课程论文结语,计算机组成原理课程论文
  13. Tomcat5.5中配置虚拟路径
  14. Centos 下配置JAVA环境
  15. 数据可视化|用散点图进行数据分析
  16. 最近的错误整理(LMY)
  17. 星光不负赶路人|2022年终总结
  18. 湖北省武汉汽车上牌篇2008年完整上牌程序供参考
  19. 2021全球十大外盘期货交易平台排名
  20. JAVA第二次作业《胖瘦程度计算》

热门文章

  1. Linux中查询显卡硬件的几种命令(记录)
  2. 矩阵论基础知识4——强大的矩阵奇异值分解(SVD)及其应用
  3. 无状态mysql_既然HTTP是无状态协议,mysql_close还有必要么?
  4. ue4sky时间_UE4 SkyLight RealTimeCapture浅析
  5. 同步和原子性---多线程学习笔记(四)
  6. 搭建express框架
  7. mysql :The user specified ... does not exist 报错
  8. ASP.NET2.0 XML系列(6): 使用XmlReaderSettings配置XmlReader的输出
  9. 巅峰对话:畅想大数据时代的车联网与智能汽车
  10. react redux 相关技术