面向对象编程(进阶)5:关键字:super
目录
5.1 super的理解
在Java类中使用super来调用父类中的指定操作:
注意:
5.2 super的使用场景
5.2.1 子类中调用父类被重写的方法
举例:
总结:
方法前面没有super.和this.
方法前面有this.
方法前面有super.
5.2.2 子类中调用父类中同名的成员变量
举例:
总结:起点不同(就近原则)
变量前面没有super.和this.
变量前面有this.
变量前面super.
特别说明:应该避免子类声明和父类重名的成员变量
5.2.3 子类构造器中调用父类构造器
情景举例1:
情景举例2:
情景举例3:
情景举例4:
情景举例5:
情景举例6:
情景举例7:
情景举例8:
5.3 小结:this与super
1、this和super的意义
this:当前对象
super:引用父类声明的成员
2、this和super的使用格式
this
super
5.4 练习
**练习1:**
**练习2:**
附加题:
练习3:
5.1 super的理解
在Java类中使用super来调用父类中的指定操作:
- super可用于访问父类中定义的属性
- super可用于调用父类中定义的成员方法
- super可用于在子类构造器中调用父类的构造器
注意:
- 尤其当子父类出现同名成员时,可以用super表明调用的是父类中的成员
- super的追溯不仅限于直接父类
- super和this的用法相像,this代表本类对象的引用,super代表父类的内存空间的标识
5.2 super的使用场景
5.2.1 子类中调用父类被重写的方法
- 如果子类没有重写父类的方法,只要权限修饰符允许,在子类中完全可以直接调用父类的方法;
- 如果子类重写了父类的方法,在子类中需要通过
super.
才能调用父类被重写的方法,否则默认调用的子类重写的方法
举例:
<span style="color:#303030"><span style="background-color:#ffffff"><span style="background-color:#282c34"><span style="color:#abb2bf"><code class="language-java"><span style="color:#c678dd">package</span> com<span style="color:#abb2bf">.</span>atguigu<span style="color:#abb2bf">.</span>inherited<span style="color:#abb2bf">.</span>method<span style="color:#abb2bf">;</span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">class</span> <span style="color:#d19a66">Phone</span> <span style="color:#abb2bf">{</span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">void</span> <span style="color:#61afef">sendMessage</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"发短信"</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">void</span> <span style="color:#61afef">call</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"打电话"</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">void</span> <span style="color:#61afef">showNum</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"来电显示号码"</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
<span style="color:#5c6370"><em>//smartphone:智能手机</em></span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">class</span> <span style="color:#d19a66">SmartPhone</span> <span style="color:#c678dd">extends</span> <span style="color:#d19a66">Phone</span><span style="color:#abb2bf">{</span>
<span style="color:#5c6370"><em>//重写父类的来电显示功能的方法</em></span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">void</span> <span style="color:#61afef">showNum</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#5c6370"><em>//来电显示姓名和图片功能</em></span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"显示来电姓名"</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"显示头像"</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#5c6370"><em>//保留父类来电显示号码的功能</em></span>
<span style="color:#c678dd">super</span><span style="color:#abb2bf">.</span><span style="color:#61afef">showNum</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span><span style="color:#5c6370"><em>//此处必须加super.,否则就是无限递归,那么就会栈内存溢出</em></span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
</code></span></span></span></span>
总结:
-
方法前面没有super.和this.
- 先从子类找匹配方法,如果没有,再从直接父类找,再没有,继续往上追溯
-
方法前面有this.
- 先从子类找匹配方法,如果没有,再从直接父类找,再没有,继续往上追溯
-
方法前面有super.
- 从当前子类的直接父类找,如果没有,继续往上追溯
5.2.2 子类中调用父类中同名的成员变量
- 如果实例变量与局部变量重名,可以在实例变量前面加this.进行区别
- 如果子类实例变量和父类实例变量重名,并且父类的该实例变量在子类仍然可见,在子类中要访问父类声明的实例变量需要在父类实例变量前加super.,否则默认访问的是子类自己声明的实例变量
- 如果父子类实例变量没有重名,只要权限修饰符允许,在子类中完全可以直接访问父类中声明的实例变量,也可以用this.实例访问,也可以用super.实例变量访问
举例:
<span style="color:#303030"><span style="background-color:#ffffff"><span style="background-color:#282c34"><span style="color:#abb2bf"><code class="language-java"><span style="color:#c678dd">class</span> <span style="color:#d19a66">Father</span><span style="color:#abb2bf">{</span>
<span style="color:#c678dd">int</span> a <span style="color:#61afef">=</span> <span style="color:#d19a66">10</span><span style="color:#abb2bf">;</span>
<span style="color:#c678dd">int</span> b <span style="color:#61afef">=</span> <span style="color:#d19a66">11</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">class</span> <span style="color:#d19a66">Son</span> <span style="color:#c678dd">extends</span> <span style="color:#d19a66">Father</span><span style="color:#abb2bf">{</span>
<span style="color:#c678dd">int</span> a <span style="color:#61afef">=</span> <span style="color:#d19a66">20</span><span style="color:#abb2bf">;</span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">void</span> <span style="color:#61afef">test</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#5c6370"><em>//子类与父类的属性同名,子类对象中就有两个a</em></span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"子类的a:"</span> <span style="color:#61afef">+</span> a<span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span><span style="color:#5c6370"><em>//20 先找局部变量找,没有再从本类成员变量找</em></span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"子类的a:"</span> <span style="color:#61afef">+</span> <span style="color:#c678dd">this</span><span style="color:#abb2bf">.</span>a<span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span><span style="color:#5c6370"><em>//20 先从本类成员变量找</em></span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"父类的a:"</span> <span style="color:#61afef">+</span> <span style="color:#c678dd">super</span><span style="color:#abb2bf">.</span>a<span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span><span style="color:#5c6370"><em>//10 直接从父类成员变量找</em></span>
<span style="color:#5c6370"><em>//子类与父类的属性不同名,是同一个b</em></span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"b = "</span> <span style="color:#61afef">+</span> b<span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span><span style="color:#5c6370"><em>//11 先找局部变量找,没有再从本类成员变量找,没有再从父类找</em></span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"b = "</span> <span style="color:#61afef">+</span> <span style="color:#c678dd">this</span><span style="color:#abb2bf">.</span>b<span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span><span style="color:#5c6370"><em>//11 先从本类成员变量找,没有再从父类找</em></span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"b = "</span> <span style="color:#61afef">+</span> <span style="color:#c678dd">super</span><span style="color:#abb2bf">.</span>b<span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span><span style="color:#5c6370"><em>//11 直接从父类局部变量找</em></span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">void</span> <span style="color:#61afef">method</span><span style="color:#abb2bf">(</span><span style="color:#c678dd">int</span> a<span style="color:#abb2bf">,</span> <span style="color:#c678dd">int</span> b<span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#5c6370"><em>//子类与父类的属性同名,子类对象中就有两个成员变量a,此时方法中还有一个局部变量a </em></span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"局部变量的a:"</span> <span style="color:#61afef">+</span> a<span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span><span style="color:#5c6370"><em>//30 先找局部变量</em></span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"子类的a:"</span> <span style="color:#61afef">+</span> <span style="color:#c678dd">this</span><span style="color:#abb2bf">.</span>a<span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span><span style="color:#5c6370"><em>//20 先从本类成员变量找</em></span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"父类的a:"</span> <span style="color:#61afef">+</span> <span style="color:#c678dd">super</span><span style="color:#abb2bf">.</span>a<span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span><span style="color:#5c6370"><em>//10 直接从父类成员变量找</em></span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"b = "</span> <span style="color:#61afef">+</span> b<span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span><span style="color:#5c6370"><em>//13 先找局部变量</em></span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"b = "</span> <span style="color:#61afef">+</span> <span style="color:#c678dd">this</span><span style="color:#abb2bf">.</span>b<span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span><span style="color:#5c6370"><em>//11 先从本类成员变量找</em></span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"b = "</span> <span style="color:#61afef">+</span> <span style="color:#c678dd">super</span><span style="color:#abb2bf">.</span>b<span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span><span style="color:#5c6370"><em>//11 直接从父类局部变量找</em></span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">class</span> <span style="color:#d19a66">Test</span><span style="color:#abb2bf">{</span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">static</span> <span style="color:#c678dd">void</span> <span style="color:#61afef">main</span><span style="color:#abb2bf">(</span><span style="color:#d19a66">String</span><span style="color:#abb2bf">[</span><span style="color:#abb2bf">]</span> args<span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">Son</span> son <span style="color:#61afef">=</span> <span style="color:#c678dd">new</span> <span style="color:#d19a66">Son</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
son<span style="color:#abb2bf">.</span><span style="color:#61afef">test</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
son<span style="color:#abb2bf">.</span><span style="color:#61afef">method</span><span style="color:#abb2bf">(</span><span style="color:#d19a66">30</span><span style="color:#abb2bf">,</span><span style="color:#d19a66">13</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
</code></span></span></span></span>
总结:起点不同(就近原则)
-
变量前面没有super.和this.
- 在构造器、代码块、方法中如果出现使用某个变量,先查看是否是当前块声明的
局部变量
, - 如果不是局部变量,先从当前执行代码的
本类去找成员变量
- 如果从当前执行代码的本类中没有找到,会往上找
父类声明的成员变量
(权限修饰符允许在子类中访问的)
- 在构造器、代码块、方法中如果出现使用某个变量,先查看是否是当前块声明的
-
变量前面有this.
- 通过this找成员变量时,先从当前执行代码的本类去找成员变量
- 如果从当前执行代码的本类中没有找到,会往上找==父类声明的成员变量(==权限修饰符允许在子类中访问的)
-
变量前面super.
- 通过super找成员变量,直接从当前执行代码的直接父类去找成员变量(权限修饰符允许在子类中访问的)
- 如果直接父类没有,就去父类的父类中找(权限修饰符允许在子类中访问的)
特别说明:应该避免子类声明和父类重名的成员变量
在阿里的开发规范等文档中都做出明确说明:
5.2.3 子类构造器中调用父类构造器
① 子类继承父类时,不会继承父类的构造器。只能通过“super(形参列表)”的方式调用父类指定的构造器。
② 规定:“super(形参列表)”,必须声明在构造器的首行。
③ 我们前面讲过,在构造器的首行可以使用"this(形参列表)",调用本类中重载的构造器,
结合②,结论:在构造器的首行,“this(形参列表)” 和 "super(形参列表)"只能二选一。
④ 如果在子类构造器的首行既没有显示调用"this(形参列表)“,也没有显式调用"super(形参列表)”,
则子类此构造器默认调用"super()",即调用父类中空参的构造器。
⑤ 由③和④得到结论:子类的任何一个构造器中,要么会调用本类中重载的构造器,要么会调用父类的构造器。
只能是这两种情况之一。
⑥ 由⑤得到:一个类中声明有n个构造器,最多有n-1个构造器中使用了"this(形参列表)“,则剩下的那个一定使用"super(形参列表)”。
开发中常见错误:
如果子类构造器中既未显式调用父类或本类的构造器,且父类中又没有空参的构造器,则
编译出错
。
情景举例1:
<span style="color:#303030"><span style="background-color:#ffffff"><span style="background-color:#282c34"><span style="color:#abb2bf"><code class="language-java"><span style="color:#c678dd">class</span> <span style="color:#d19a66">A</span><span style="color:#abb2bf">{</span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">class</span> <span style="color:#d19a66">B</span> <span style="color:#c678dd">extends</span> <span style="color:#d19a66">A</span><span style="color:#abb2bf">{</span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">class</span> <span style="color:#d19a66">Test</span><span style="color:#abb2bf">{</span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">static</span> <span style="color:#c678dd">void</span> <span style="color:#61afef">main</span><span style="color:#abb2bf">(</span><span style="color:#d19a66">String</span><span style="color:#abb2bf">[</span><span style="color:#abb2bf">]</span> args<span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">B</span> b <span style="color:#61afef">=</span> <span style="color:#c678dd">new</span> <span style="color:#d19a66">B</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#5c6370"><em>//A类和B类都是默认有一个无参构造,B类的默认无参构造中还会默认调用A类的默认无参构造</em></span>
<span style="color:#5c6370"><em>//但是因为都是默认的,没有打印语句,看不出来</em></span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
</code></span></span></span></span>
情景举例2:
<span style="color:#303030"><span style="background-color:#ffffff"><span style="background-color:#282c34"><span style="color:#abb2bf"><code class="language-java"><span style="color:#c678dd">class</span> <span style="color:#d19a66">A</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">A</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"A类无参构造器"</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">class</span> <span style="color:#d19a66">B</span> <span style="color:#c678dd">extends</span> <span style="color:#d19a66">A</span><span style="color:#abb2bf">{</span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">class</span> <span style="color:#d19a66">Test</span><span style="color:#abb2bf">{</span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">static</span> <span style="color:#c678dd">void</span> <span style="color:#61afef">main</span><span style="color:#abb2bf">(</span><span style="color:#d19a66">String</span><span style="color:#abb2bf">[</span><span style="color:#abb2bf">]</span> args<span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">B</span> b <span style="color:#61afef">=</span> <span style="color:#c678dd">new</span> <span style="color:#d19a66">B</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#5c6370"><em>//A类显示声明一个无参构造,</em></span>
<span style="color:#5c6370"><em>//B类默认有一个无参构造,</em></span>
<span style="color:#5c6370"><em>//B类的默认无参构造中会默认调用A类的无参构造</em></span>
<span style="color:#5c6370"><em>//可以看到会输出“A类无参构造器"</em></span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
</code></span></span></span></span>
情景举例3:
<span style="color:#303030"><span style="background-color:#ffffff"><span style="background-color:#282c34"><span style="color:#abb2bf"><code class="language-java"><span style="color:#c678dd">class</span> <span style="color:#d19a66">A</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">A</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"A类无参构造器"</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">class</span> <span style="color:#d19a66">B</span> <span style="color:#c678dd">extends</span> <span style="color:#d19a66">A</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">B</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"B类无参构造器"</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">class</span> <span style="color:#d19a66">Test</span><span style="color:#abb2bf">{</span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">static</span> <span style="color:#c678dd">void</span> <span style="color:#61afef">main</span><span style="color:#abb2bf">(</span><span style="color:#d19a66">String</span><span style="color:#abb2bf">[</span><span style="color:#abb2bf">]</span> args<span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">B</span> b <span style="color:#61afef">=</span> <span style="color:#c678dd">new</span> <span style="color:#d19a66">B</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#5c6370"><em>//A类显示声明一个无参构造,</em></span>
<span style="color:#5c6370"><em>//B类显示声明一个无参构造, </em></span>
<span style="color:#5c6370"><em>//B类的无参构造中虽然没有写super(),但是仍然会默认调用A类的无参构造</em></span>
<span style="color:#5c6370"><em>//可以看到会输出“A类无参构造器"和"B类无参构造器")</em></span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
</code></span></span></span></span>
情景举例4:
<span style="color:#303030"><span style="background-color:#ffffff"><span style="background-color:#282c34"><span style="color:#abb2bf"><code class="language-java"><span style="color:#c678dd">class</span> <span style="color:#d19a66">A</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">A</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"A类无参构造器"</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">class</span> <span style="color:#d19a66">B</span> <span style="color:#c678dd">extends</span> <span style="color:#d19a66">A</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">B</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#c678dd">super</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"B类无参构造器"</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">class</span> <span style="color:#d19a66">Test</span><span style="color:#abb2bf">{</span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">static</span> <span style="color:#c678dd">void</span> <span style="color:#61afef">main</span><span style="color:#abb2bf">(</span><span style="color:#d19a66">String</span><span style="color:#abb2bf">[</span><span style="color:#abb2bf">]</span> args<span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">B</span> b <span style="color:#61afef">=</span> <span style="color:#c678dd">new</span> <span style="color:#d19a66">B</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#5c6370"><em>//A类显示声明一个无参构造,</em></span>
<span style="color:#5c6370"><em>//B类显示声明一个无参构造, </em></span>
<span style="color:#5c6370"><em>//B类的无参构造中明确写了super(),表示调用A类的无参构造</em></span>
<span style="color:#5c6370"><em>//可以看到会输出“A类无参构造器"和"B类无参构造器")</em></span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
</code></span></span></span></span>
情景举例5:
<span style="color:#303030"><span style="background-color:#ffffff"><span style="background-color:#282c34"><span style="color:#abb2bf"><code class="language-java"><span style="color:#c678dd">class</span> <span style="color:#d19a66">A</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">A</span><span style="color:#abb2bf">(</span><span style="color:#c678dd">int</span> a<span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"A类有参构造器"</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">class</span> <span style="color:#d19a66">B</span> <span style="color:#c678dd">extends</span> <span style="color:#d19a66">A</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">B</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"B类无参构造器"</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">class</span> <span style="color:#d19a66">Test05</span><span style="color:#abb2bf">{</span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">static</span> <span style="color:#c678dd">void</span> <span style="color:#61afef">main</span><span style="color:#abb2bf">(</span><span style="color:#d19a66">String</span><span style="color:#abb2bf">[</span><span style="color:#abb2bf">]</span> args<span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">B</span> b <span style="color:#61afef">=</span> <span style="color:#c678dd">new</span> <span style="color:#d19a66">B</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#5c6370"><em>//A类显示声明一个有参构造,没有写无参构造,那么A类就没有无参构造了</em></span>
<span style="color:#5c6370"><em>//B类显示声明一个无参构造, </em></span>
<span style="color:#5c6370"><em>//B类的无参构造没有写super(...),表示默认调用A类的无参构造</em></span>
<span style="color:#5c6370"><em>//编译报错,因为A类没有无参构造</em></span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
</code></span></span></span></span>
情景举例6:
<span style="color:#303030"><span style="background-color:#ffffff"><span style="background-color:#282c34"><span style="color:#abb2bf"><code class="language-java"><span style="color:#c678dd">class</span> <span style="color:#d19a66">A</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">A</span><span style="color:#abb2bf">(</span><span style="color:#c678dd">int</span> a<span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"A类有参构造器"</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">class</span> <span style="color:#d19a66">B</span> <span style="color:#c678dd">extends</span> <span style="color:#d19a66">A</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">B</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#c678dd">super</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"B类无参构造器"</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">class</span> <span style="color:#d19a66">Test06</span><span style="color:#abb2bf">{</span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">static</span> <span style="color:#c678dd">void</span> <span style="color:#61afef">main</span><span style="color:#abb2bf">(</span><span style="color:#d19a66">String</span><span style="color:#abb2bf">[</span><span style="color:#abb2bf">]</span> args<span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">B</span> b <span style="color:#61afef">=</span> <span style="color:#c678dd">new</span> <span style="color:#d19a66">B</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#5c6370"><em>//A类显示声明一个有参构造,没有写无参构造,那么A类就没有无参构造了</em></span>
<span style="color:#5c6370"><em>//B类显示声明一个无参构造, </em></span>
<span style="color:#5c6370"><em>//B类的无参构造明确写super(),表示调用A类的无参构造</em></span>
<span style="color:#5c6370"><em>//编译报错,因为A类没有无参构造</em></span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
</code></span></span></span></span>
情景举例7:
<span style="color:#303030"><span style="background-color:#ffffff"><span style="background-color:#282c34"><span style="color:#abb2bf"><code class="language-java"><span style="color:#c678dd">class</span> <span style="color:#d19a66">A</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">A</span><span style="color:#abb2bf">(</span><span style="color:#c678dd">int</span> a<span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"A类有参构造器"</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">class</span> <span style="color:#d19a66">B</span> <span style="color:#c678dd">extends</span> <span style="color:#d19a66">A</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">B</span><span style="color:#abb2bf">(</span><span style="color:#c678dd">int</span> a<span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#c678dd">super</span><span style="color:#abb2bf">(</span>a<span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"B类有参构造器"</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">class</span> <span style="color:#d19a66">Test07</span><span style="color:#abb2bf">{</span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">static</span> <span style="color:#c678dd">void</span> <span style="color:#61afef">main</span><span style="color:#abb2bf">(</span><span style="color:#d19a66">String</span><span style="color:#abb2bf">[</span><span style="color:#abb2bf">]</span> args<span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">B</span> b <span style="color:#61afef">=</span> <span style="color:#c678dd">new</span> <span style="color:#d19a66">B</span><span style="color:#abb2bf">(</span><span style="color:#d19a66">10</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#5c6370"><em>//A类显示声明一个有参构造,没有写无参构造,那么A类就没有无参构造了</em></span>
<span style="color:#5c6370"><em>//B类显示声明一个有参构造, </em></span>
<span style="color:#5c6370"><em>//B类的有参构造明确写super(a),表示调用A类的有参构造</em></span>
<span style="color:#5c6370"><em>//会打印“A类有参构造器"和"B类有参构造器"</em></span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
</code></span></span></span></span>
情景举例8:
<span style="color:#303030"><span style="background-color:#ffffff"><span style="background-color:#282c34"><span style="color:#abb2bf"><code class="language-java"><span style="color:#c678dd">class</span> <span style="color:#d19a66">A</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">A</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"A类无参构造器"</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#d19a66">A</span><span style="color:#abb2bf">(</span><span style="color:#c678dd">int</span> a<span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"A类有参构造器"</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">class</span> <span style="color:#d19a66">B</span> <span style="color:#c678dd">extends</span> <span style="color:#d19a66">A</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">B</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#c678dd">super</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span><span style="color:#5c6370"><em>//可以省略,调用父类的无参构造</em></span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"B类无参构造器"</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#d19a66">B</span><span style="color:#abb2bf">(</span><span style="color:#c678dd">int</span> a<span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#c678dd">super</span><span style="color:#abb2bf">(</span>a<span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span><span style="color:#5c6370"><em>//调用父类有参构造</em></span>
<span style="color:#d19a66">System</span><span style="color:#abb2bf">.</span>out<span style="color:#abb2bf">.</span><span style="color:#61afef">println</span><span style="color:#abb2bf">(</span><span style="color:#98c379">"B类有参构造器"</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
<span style="color:#c678dd">class</span> <span style="color:#d19a66">Test8</span><span style="color:#abb2bf">{</span>
<span style="color:#c678dd">public</span> <span style="color:#c678dd">static</span> <span style="color:#c678dd">void</span> <span style="color:#61afef">main</span><span style="color:#abb2bf">(</span><span style="color:#d19a66">String</span><span style="color:#abb2bf">[</span><span style="color:#abb2bf">]</span> args<span style="color:#abb2bf">)</span><span style="color:#abb2bf">{</span>
<span style="color:#d19a66">B</span> b1 <span style="color:#61afef">=</span> <span style="color:#c678dd">new</span> <span style="color:#d19a66">B</span><span style="color:#abb2bf">(</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#d19a66">B</span> b2 <span style="color:#61afef">=</span> <span style="color:#c678dd">new</span> <span style="color:#d19a66">B</span><span style="color:#abb2bf">(</span><span style="color:#d19a66">10</span><span style="color:#abb2bf">)</span><span style="color:#abb2bf">;</span>
<span style="color:#abb2bf">}</span>
<span style="color:#abb2bf">}</span>
</code></span></span></span></span>
5.3 小结:this与super
1、this和super的意义
this:当前对象
- 在构造器和非静态代码块中,表示正在new的对象
- 在实例方法中,表示调用当前方法的对象
super:引用父类声明的成员
2、this和super的使用格式
-
this
- this.成员变量:表示当前对象的某个成员变量,而不是局部变量
- this.成员方法:表示当前对象的某个成员方法,完全可以省略this.
- this()或this(实参列表):调用另一个构造器协助当前对象的实例化,只能在构造器首行,只会找本类的构造器,找不到就报错
-
super
- super.成员变量:表示当前对象的某个成员变量,该成员变量在父类中声明的
- super.成员方法:表示当前对象的某个成员方法,该成员方法在父类中声明的
- super()或super(实参列表):调用父类的构造器协助当前对象的实例化,只能在构造器首行,只会找直接父类的对应构造器,找不到就报错
5.4 练习
**练习1:**
修改方法重写的练习2中定义的类Kids中employeed()方法,在该方法中调用父类ManKind的employeed()方法,然后再输出“but Kids should study and no job.”
**练习2:**
修改继承中的练习3中定义的Cylinder类,在Cylinder类中覆盖findArea()方法,计算圆柱的表面积。考虑:findVolume方法怎样做相应的修改?
在CylinderTest类中创建Cylinder类的对象,设置圆柱的底面半径和高,并输出圆柱的表面积和体积。
附加题:
在CylinderTest类中创建一个Circle类的对象,设置圆的半径,计算输出圆的面积。体会父类和子类成员的分别调用。
练习3:
1、写一个名为Account的类模拟账户。该类的属性和方法如下图所示。该类包括的属性:账号id,余额balance,年利率annualInterestRate;包含的方法:访问器方法(getter和setter方法),返回月利率的方法getMonthlyInterest(),取款方法withdraw(),存款方法deposit()。
写一个用户程序测试Account类。在用户程序中,创建一个账号为1122、余额为20000、年利率4.5%的Account对象。使用withdraw方法提款30000元,并打印余额。
再使用withdraw方法提款2500元,使用deposit方法存款3000元,然后打印余额和月利率。
提示:在提款方法withdraw中,需要判断用户余额是否能够满足提款数额的要求,如果不能,应给出提示。
运行结果如图所示:
2、创建Account类的一个子类CheckAccount代表可透支的账户,该账户中定义一个属性overdraft代表可透支限额。在CheckAccount类中重写withdraw方法,其算法如下:
<span style="color:#303030"><span style="background-color:#ffffff"><span style="background-color:#282c34"><span style="color:#abb2bf"><code class="language- language-none">如果(取款金额<账户余额),
可直接取款
如果(取款金额>账户余额),
计算需要透支的额度
判断可透支额overdraft是否足够支付本次透支需要,如果可以
将账户余额修改为0,冲减可透支金额
如果不可以
提示用户超过可透支额的限额
</code></span></span></span></span>
要求:写一个用户程序测试CheckAccount类。在用户程序中,创建一个账号为1122、余额为20000、年利率4.5%,可透支限额为5000元的CheckAccount对象。
使用withdraw方法提款5000元,并打印账户余额和可透支额。
再使用withdraw方法提款18000元,并打印账户余额和可透支额。
再使用withdraw方法提款3000元,并打印账户余额和可透支额。
提示:
(1)子类CheckAccount的构造方法需要将从父类继承的3个属性和子类自己的属性全部初始化。
(2)父类Account的属性balance被设置为private,但在子类CheckAccount的withdraw方法中需要修改它的值,因此应修改父类的balance属性,定义其为protected。
运行结果如下图所示: