Java的继承 以学生管理系统为例

为什么要继承

继承就是子类继承父类的变量和函数,通过继承,可以使代码更加简洁,可维护性更强。

比如当我们想编写的两个类拥有很多相似的变量和函数时,我们可以写一个父类,其中包含这两个子类共有的变量与函数,两个子类继承这个父类之后就可以直接调用这些变量与函数,同时也可以在子类里面定义该子类特有的变量与函数。既简化了代码,又使得维护代码时需要修改的部分减少了,提高了可维护性。

继承的特点

子类拥有父类非 private 的属性、方法。

子类可以拥有自己的属性和方法,即子类可以对父类进行扩展。

子类可以用自己的方式实现父类的方法。

Java 的继承是单继承,但是可以多重继承,单继承就是一个子类只能继承一个父类,多重继承就是,例如 B 类继承 A 类,C 类继承 B 类,所以按照关系就是 B 类是 C 类的父类,A 类是 B 类的父类,这是 Java 继承区别于 C++ 继承的一个特性。

提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。

继承的实现

extends

一般通过extends实现继承,该关键字为单一继承(不能一个类继承多个类),如

class A extends B{
}

就是A类继承B类。

还有一种继承实现并不常用,为implements,使用范围为类继承接口的情况,暂时略过不提。

下面给出一段有关继承的代码,也是学生管理系统,其中CSStu(计算机学生)类继承Student(学生)类。在后面的讲解中也将用到这段代码。

package test;

class Student{//父类
	String name;
	int age;
	double grade;
	public Student(){//无参数
		System.out.println("父类的无参数构造器被调用");
	}
	public Student(String name,int age,double grade) {//有参数
		System.out.println("父类的有参数构造器被调用");
		this.name=name;
		this.age=age;
		this.grade=grade;
	}
	public void Stuprint() {
		System.out.println("name:"+name);
		System.out.println("age:"+age);
		System.out.println("grade:"+grade);
	}
}
class CSStu extends Student{//子类
	public CSStu(){//无参数
		System.out.println("子类的无参数构造器被调用");
	}
	public CSStu(String name,int age,double grade) {//有参数
		super(name,age,grade);
		System.out.println("子类的有参数构造器被调用");
	}
	public void CSprint() {
		System.out.println("This is a CS Student.");
		super.Stuprint();
	}
}

public class Inheritance {
	public static void main(String[] args) {
		CSStu ShadyPi=new CSStu();//调用无参数构造器定义一个空CSStu对象
		ShadyPi.Stuprint();
		CSStu Pi=new CSStu("ShadyPi",19,0.1);
		Pi.Stuprint();
		Pi.CSprint();
	}
}

这段代码的运行结果如下:

父类的无参数构造器被调用
子类的无参数构造器被调用
name:null
age:0
grade:0.0
父类的有参数构造器被调用
子类的有参数构造器被调用
name:ShadyPi
age:19
grade:0.1
This is a CS Student.
name:ShadyPi
age:19
grade:0.1

super和this

顾名思义,super指向当前对象的父类,而this指向自己,一般用在类的声明里。

可以看到,在定义函数CSprint时,我们直接用super调用了父类的Stuprint函数,同时还可以加入别的操作,使得编程更简洁高效。

public void CSprint() {
		System.out.println("This is a CS Student.");
		super.Stuprint();
	}

构造器

可以看到,在定义父类Student和子类CSStu时,我们分别写了两个构造器,一个是有参数的,一个是无参数的。

子类是不继承父类的构造器(构造方法或者构造函数)的,它只是调用(隐式或显式)。如果父类的构造器带有参数,则必须在子类的构造器中显式地通过 super 关键字调用父类的构造器并配以适当的参数列表。

如果父类构造器没有参数,则在子类的构造器中不需要使用 super 关键字调用父类构造器,系统会自动调用父类的无参构造器。

需要注意的是,若要调用有参数的父类构造器,构造语句需要写在第一行,否则会CE。

public CSStu(String name,int age,double grade) {//有参数
		super(name,age,grade);
		System.out.println("子类的有参数构造器被调用");
	}

从输出也可以看到函数的调用顺序,可以发现无论有参数还是无参数构造器,进入子类构造器后第一个触发的就是父类构造器。

父类的无参数构造器被调用
子类的无参数构造器被调用
name:null
age:0
grade:0.0
父类的有参数构造器被调用
子类的有参数构造器被调用

其他函数

前面说到,子类会继承父类的所有变量与函数,所以子类除了在定义过程中通过super调用,还可以直接在外部直接调用,如

public static void main(String[] args) {
		CSStu ShadyPi=new CSStu();
		ShadyPi.Stuprint();
		CSStu Pi=new CSStu("ShadyPi",19,0.1);
		Pi.Stuprint();
		Pi.CSprint();
	}

CSStu类的对象Pi仍然可以直接调用定义在Student类的Stuprint函数。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ShadyPi

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值