继承的概念
在前面我们就提到面向对象的三大特性,其中之一就是继承,今天我们详解java中继承的定义。
我们在写代码中有时会遇到这种情况,比如说我们要写一个Human的类,那么这个类中的属性包括姓名,年龄,性别等等,然后我们又要写一个Student的类,这个类里面也有姓名,年龄和性别以及其他的属性,这时候我们难道在每个类中都要把这三个属性写一遍吗?那么如果类有很多呢?怕是不理智吧,这样就是的代码大量的冗余,性能下降。
这个时候我们就可以用到继承的概念,只用在Human类中写一次,Student类可以继承Human类,这时候我们把Huamn叫做父类,把Student类叫做子类。子类也被叫做派生类,父类也被叫做超类
继承的实现
在java中使用extends
关键字来实现继承,语法如下:
class 子类 extends 父类
看个例子:
class Person{
private String name;
private int age;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
class Student extends Person{ //定义了一个子类
}
public class Test {
public static void main(String[] args) {
Student student = new Student();
student.setName("Steven");
student.setAge(18);
System.out.println("姓名:"+student.getName()+",年龄:"+student.getAge());
}
}
在上面的代码中,我们定义了一个Person类,又定义了一个继承于它的Student子类,但是子类中什么也没有写,那么我们在main方法中实例化一个子类的对象,结果会时什么呢?这时候就有人很迷了,子类什么都没写,怎么会有结果呢?
那么我们先看看结果:
事实证明是有结果的,那么这个是为什么呢?
看了上面的代码及运行结果,你就不难理解当发生了类继承关系之后,子类可以直接继承父类的操作,可以实现代码的重用。子类最低也维持和父类相同的功能。
子类里面虽然什么也没有写,但是默认继承了父类的属性以及方法
当然子类不仅可以如此,还可以进行功能的扩充。例如:扩充属性和方法。
如下:
class Student extends Person{ //定义了一个子类
private String school; //扩充的新属性
public String getSchool() {
return school;
}
public void setSchool(String school) {
this.school = school;
}
}
public class Test {
public static void main(String[] args) {
Student student = new Student();
student.setName("Steven");
student.setAge(18);
student.setSchool("高新一中");
System.out.println("姓名:"+student.getName()+",年龄:"+student.getAge()+",学校:"+student.getSchool());
}
}
继承的主要作用是对类的扩充以及代码的重用
继承的限制
子类对象在进行实例化前一定会首先实例化父类对象。默认调用父类的构造方法后再调用子类构造方法进行子类对象初始化。
看一段代码:
class Person{
public Person(){
System.out.println("**Person类对象产生**");
}
}
class Student extends Person{
public Student(){
super() ; //此语句在无参时写于不写一样
System.out.println("**Student类对象产生**");
}
}
public class Test{
public static void main(String[] args) {
new Student();
}
}
在上面这段代码中,子类的构造方法中有个super(),就是调用的父类的构造方法,当父类构造方法是无参的时候,可以省略,会默认调用父类的构造方法。
以上代码我们发现,没有任何一条语句调用父类构造方法。因此,子类对象实例化之前一定先实例化父类对象。
注意:实际上在子类的构造方法之中,相当于隐含了一个语句 super(); 同时需要注意的是,如果父类里没有提供无参构造,那么这个时候就必须使用super()明确指明你要调用的父类构造 方法。
java不允许多继承,但允许多层继承
也就是说一个子类只能有一个父类
在进行继承的时候,子类会继承父类的所有结构。(包含私有属性、构造方法、普通方法)但是这个时候需要注意的是,所有的非私有操作属于显示继承(可以直接调用),所有的私有操作属于隐式继承通过其他形式调用,例如setter或getter)
通过代码看看显式继承与隐式继承:
class Person{
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Student extends Person{
public void fun(){
System.out.println(getName());
}
}
public class Test {
public static void main(String[] args) {
Student student = new Student();
student.setName("Steven");
System.out.println(student.getName());
student.fun();
}
}
此时父类中的属性的确被子类所继承了,但是发现子类能够使用的是所有非private操作,而所有的private操作无法被直接使用,所以称为隐式继承。
再来总结一下:
- 继承的语法以及继承的目的(扩展已有类的功能,使代码重用)
- 子类对象的实例化流程:不管如何操作,一定要先实例化父类对象。
- 不允许多重继承,只允许多层继承。