目录
1.3.1子类中调用无参构造方法时会先调用父类中的无参构造方法。
1.3.2父类中没有无参构造方法,只有有参构造方法,会如何?
1.1继承概述
继承:面向对象三大特性之一,可以使得子类继承父类中的属性和方法,并且还能在子类中定义自己的属性和方法。
继承的格式:public class 子类名 extends 父类名{}
接下来将从下面代码说明为何要使用继承:


从上述两段代码可以看出这两个类有相同的属性还有一些相同的方法,这样类中代码重复性较高。那么我们是否可以将这些重复的属性和方法放在同一个类中呢?
public class Animal{
public String name;
public int age;
public void setName(String name){
this.name=name;
}
public String getName(){
return name;
}
public void setAge(int age){
this.name=name;
}
public int getAge(){
return age;
}
}
public class Cat{
public eatMeat(){
System.out.println("猫吃肉");
}
}
public class Sheep{
public eatGlass(){
System.out.println("羊吃草");
}
}
1.2 继承的好处和弊端
由上述例子,我们可以看出继承有以下好处:
- 提高了代码的复用性(多个类相同的成员可以放到一个类里)
- 提高了代码的维护性(如果方法的代码需要修改,修改一处即可)
继承的弊端如下:
加强了程序的耦合性,当父类中的内容修改时,继承了父类内容的子类也不得不跟着修改,降低了子类的独立性。
1.3 继承中经常遇到的问题
1.3.1子类中调用无参构造方法时会先调用父类中的无参构造方法。
请看以下例子:
父类代码如下所示:
package com.inherit;
public class Fu {
//属性
String name;
int age;
//父类的无参构造方法
public Fu(){
System.out.println("父类无参构造方法");
}
//父类的有参构造方法
public Fu(String name, int age){
this.name = name;
this.age = age;
System.out.println("父类的有参构造方法");
}
}
子类代码如下所示:
package com.inherit;
public class Zi extends Fu{
//子类无参构造方法
public Zi(){
System.out.println("子类无参构造方法");
}
//子类有参构造方法
public Zi(int age){
System.out.println("子类的有参构造方法");
}
}
测试类如下所示:
package com.inherit;
public class demo {
public static void main(String args[]){
//创建子类
Zi z = new Zi();
}
}
上述代码运行后的结果如下所示:
父类无参构造方法
子类无参构造方法
Process finished with exit code 0
看到上述结果,我们肯定会很好奇,为何我们明明创建的是子类的对象,但是会调用父类的无参构造方法呢?原因如下所示:
- 因为子类会继承父类中的数据,而且还极有可能使用父类中的数据,所以子类中数据初始化之前,会先初始化父类中的数据。
- 每一个子类的无参构造函数第一条语句都是默认的super(),即默认调用父类无参构造方法。
1.3.2父类中没有无参构造方法,只有有参构造方法,会如何?
若父类中没有无参构造方法,只有有参构造方法的话,如下所示,子类会报错。
父类代码如下所示:
package com.inherit;
public class Fu {
//属性
String name;
int age;
//父类的有参构造方法
public Fu(String name, int age){
this.name = name;
this.age = age;
System.out.println("父类的有参构造方法");
}
}
若想解决这个问题,可以通过以下两种途径:
- 子类通过使用super关键字显示的调用父类的有参构造方法,子类具体代码,如下代码1所示:
- 在父类中自己添加一个无参构造函数即可(推荐使用)
package com.inherit;
public class Zi extends Fu{
//子类无参构造方法
public Zi(){
super("豆豆", 10);
System.out.println("子类无参构造方法");
}
//子类有参构造方法
public Zi(int age){
super("豆豆", 10);
System.out.println("子类的有参构造方法");
}
}
代码1
1.3.3继承中成员方法的访问特点
通过一个子类对象访问一个方法的顺序:
- 先在子类成员范围内找
- 再在父类成员范围内找
- 如果没有就会报错(不考虑父亲的父亲)
以下代码是子类对象调用show()方法的时候,首先在子类成员范围内找,若子类成员中存在,则直接调用。
父类代码如下所示:
package com.inherit;
public class Fu {
//属性
String name;
int age;
//父类的无参构造方法
public Fu(){
System.out.println("父类无参构造方法");
}
//父类的有参构造方法
public Fu(String name, int age){
this.name = name;
this.age = age;
System.out.println("父类的有参构造方法");
}
public void show(){
System.out.println("父类中的show方法");
}
}
子类代码如下所示:
package com.inherit;
public class Zi extends Fu{
//子类无参构造方法
public Zi(){
System.out.println("子类无参构造方法");
}
//子类有参构造方法
public Zi(int age){
System.out.println("子类的有参构造方法");
}
public void show(){
System.out.println("子类中的show方法");
}
}
测试类代码如下所示:
package com.inherit;
public class demo {
public static void main(String args[]){
//创建子类
Zi z = new Zi();
z.show();
}
}
代码运行结果如下所示:
父类无参构造方法
子类无参构造方法
子类中的show方法
以下代码是子类对象调用show()方法的时候,首先在子类成员范围内找,若子类成员中不存在,继续在父类成员范围内寻找,若存在,则调用,若不存在,则报错(不考虑父亲的父亲的情况):
父类代码:
package com.inherit;
public class Fu {
//属性
String name;
int age;
//父类的无参构造方法
public Fu(){
System.out.println("父类无参构造方法");
}
//父类的有参构造方法
public Fu(String name, int age){
this.name = name;
this.age = age;
System.out.println("父类的有参构造方法");
}
public void show(){
System.out.println("父类中的show方法");
}
}
子类代码如下所示:
package com.inherit;
public class Zi extends Fu{
//子类无参构造方法
public Zi(){
System.out.println("子类无参构造方法");
}
//子类有参构造方法
public Zi(int age){
System.out.println("子类的有参构造方法");
}
}
测试代码如下所示:
package com.inherit;
public class demo {
public static void main(String args[]){
//创建子类
Zi z = new Zi();
z.show();
}
}
该程序运行结果如下所示:
父类无参构造方法
子类无参构造方法
父类中的show方法
1.3.4子类是否能继承父类的私有属性和方法?
子类不能继承父类的私有属性,具体代码如下所示:
父类代码如下所示:
package com.inherit;
public class Fu {
//属性
private String name = "豆豆";
private int age = 10;
//父类的无参构造方法
public Fu(){
System.out.println("父类无参构造方法");
}
//父类的有参构造方法
public Fu(String name, int age){
System.out.println("父类的有参构造方法");
}
public void show(){
System.out.println("父类中的show方法");
}
}
子类代码如下所示:
package com.inherit;
public class Zi extends Fu{
//子类无参构造方法
public Zi(){
System.out.println("子类无参构造方法");
}
//子类有参构造方法
public Zi(int age){
System.out.println("子类的有参构造方法");
}
public void show(){
System.out.println(name); //报错
}
}
在上述程序中,子类使用从父类继承下来的属性name,由于这个属性在父类中是private类型,故子类不能继承,所以子类show()方法报错。
子类不能继承父类的私有方法,具体代码如下所示:
父类代码如下所示:
package com.inherit;
public class Fu {
//属性
private String name = "豆豆";
private int age = 10;
//父类的无参构造方法
public Fu(){
System.out.println("父类无参构造方法");
}
//父类的有参构造方法
public Fu(String name, int age){
System.out.println("父类的有参构造方法");
}
public void show(){
System.out.println("父类中的show方法");
}
private void print(){
System.out.println("父类中的私有方法");
}
}
子类代码如下所示:
package com.inherit;
public class Zi extends Fu{
//子类无参构造方法
public Zi(){
System.out.println("子类无参构造方法");
}
//子类有参构造方法
public Zi(int age){
System.out.println("子类的有参构造方法");
}
public void show(){
System.out.println("子类的show方法");
}
}
测试类如下所示:
package com.inherit;
public class demo {
public static void main(String args[]){
//创建子类
Zi z = new Zi();
z.print(); //报错
}
}
在上述程序中,子类无法继承父类中的私有方法print(),故在测试类中通过子类对象调用该方法的时候将会报错。
1.3.5继承的注意事项
- Java只支持单继承,不支持多继承。即子类不能同时继承多个父类。 比如说不能写成这种形式:public class extends Father,Mother{}
- 方法重写的时候,子类方法访问的权限不能比父类低。访问权限public>protected>private 如果父类的访问权限是protected,那么子类的访问权限只能是protected或者public。
1.4方法重写
方法重写:子类中出现了和父类一样的方法声明,就是方法重写。
- 当子类需要父类的功能,而功能主体又有自己特有的内容的时候,可以重写父类中的方法。这样既可以沿袭父类中的功能,又可以定义子类中特有的功能。
- 为了防止在重写的时候,把方法名写错,可以使用@Override注解来检查错误。
方法重写的注意事项:
- 由于子类不能继承父类中的私有方法,故不能在子类中重写父类中的私有方法
- 方法重写的时候,子类的访问权限不能比父类低。
1137

被折叠的 条评论
为什么被折叠?



