第三次学JAVA再学不好就吃翔(part31)--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(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关键字相关推荐
- 第三次学JAVA再学不好就吃翔(part107)--字符流的拷贝
学习笔记,仅供参考,有错必纠 文章目录 IO流 字符流的拷贝 拷贝纯文本文件 注意事项 自定义字符数组的拷贝 IO流 字符流的拷贝 拷贝纯文本文件 zzz.txt: 安徽财经大学 JAVA代码: pa ...
- 第三次学JAVA再学不好就吃翔(part30)--继承
学习笔记,仅供参考 文章目录 面向对象 继承 先来个例子 继承的好处和弊端 Java中类的继承特点 继承的注意事项 面向对象 继承 继承(extends),让类与类之间产生关系,比如子父类关系. 先来 ...
- 第三次学JAVA再学不好就吃翔(part106)--字符流
学习笔记,仅供参考,有错必纠 文章目录 IO流 字符流输入流FileReader 字符流是什么 FileReader类构造方法 举个例子 字符流输出流FileWriter FileWriter构造方法 ...
- 第三次学JAVA再学不好就吃翔(part46)--Scanner类
学习笔记,仅供参考 文章目录 Scanner类 Scanner获取数据出现的问题 Scanner类 概述 Scanner是在java.util包下的一个类,使用该类时我们需要导包.这个类被final修 ...
- 第三次学JAVA再学不好就吃翔(part117)--单例设计模式
学习笔记,仅供参考,有错必纠 文章目录 多线程 单例设计模式 饿汉式 懒汉式 第三种格式 Timer类 线程的五种状态 多线程 单例设计模式 单例设计模式,即保证类在内存中只有一个对象,如何保证类在内 ...
- 第三次学JAVA再学不好就吃翔(part109)--LineNumberReader类
学习笔记,仅供参考,有错必纠 IO流 LineNumberReader类 该类继承自java.io.BufferedReader,该类可以跟踪行号的缓冲字符输入流.此类定义了方法 setLineNum ...
- 第三次学JAVA再学不好就吃翔(part108)--带缓冲的字符流
学习笔记,仅供参考,有错必纠 文章目录 IO流 带缓冲的字符流 BufferedReader和BufferedWriter readLine和newLine方法 IO流 带缓冲的字符流 Buffere ...
- 第三次学JAVA再学不好就吃翔(part7)--基础语法之运算符
学习笔记,仅供参考 文章目录 JAVA基础语法 运算符 算数运算符 算术运算符 ++和-- 赋值运算符 关系运算符 JAVA基础语法 运算符 什么是运算符 就是对常量和变量进行操作的符号. 运算符的分 ...
- 第三次学JAVA再学不好就吃翔(part115)--多线程
学习笔记,仅供参考,有错必纠 文章目录 多线程 多线程引入 什么是线程 多线程并行和并发的区别 Java程序运行原理 多线程的实现方式 多线程实现的方式1 多线程程序实现的方式2 以上两种实现方式的区 ...
最新文章
- 报错-Unknown class in Interface Builder file
- 静态程序分析chapter2 - IR(Jimple) 和 CFG
- 使用weka进行Cross-validation实验
- 计算机自动启动无法开机,为何插上电源 电脑会自动开机 但是又开不起来
- axure 调整中继器列宽_在Axure中用“中继器”实现对表格的增、删、改
- 如何在 vue-cli v3.0 中使用 SCSS/SASS
- 浙大计算机专硕培养方案,浙江大学硕士研究生培养方案
- 5专题总结-数据结构
- C语言递归算法(一)
- Python字典中 get() 函数的使用
- HTTP2.0,HTTP1.1,HTTP1.0三者在通性性能上的优化方法
- 计算机组成原理课程论文结语,计算机组成原理课程论文
- Tomcat5.5中配置虚拟路径
- Centos 下配置JAVA环境
- 数据可视化|用散点图进行数据分析
- 最近的错误整理(LMY)
- 星光不负赶路人|2022年终总结
- 湖北省武汉汽车上牌篇2008年完整上牌程序供参考
- 2021全球十大外盘期货交易平台排名
- JAVA第二次作业《胖瘦程度计算》
热门文章
- Linux中查询显卡硬件的几种命令(记录)
- 矩阵论基础知识4——强大的矩阵奇异值分解(SVD)及其应用
- 无状态mysql_既然HTTP是无状态协议,mysql_close还有必要么?
- ue4sky时间_UE4 SkyLight RealTimeCapture浅析
- 同步和原子性---多线程学习笔记(四)
- 搭建express框架
- mysql :The user specified ... does not exist 报错
- ASP.NET2.0 XML系列(6): 使用XmlReaderSettings配置XmlReader的输出
- 巅峰对话:畅想大数据时代的车联网与智能汽车
- react redux 相关技术