继承是面向对象的第二大主要特性,而继承性要解决的就是代码重用的问题,利用继承性可以从已有的类继续派生出新的子类,也可以利用子类扩展出更多的操作功能
继承问题的引出
Person.java:
class Person {
private String name ;
private int age ;
// setter、getter略
}
Student.java:
class Student {
private String name;
private int age;
private String school;
// setter、getter略
}
通过以上两段代码的比较,如果按照之前所学习到的概念进行开发的话,那么程序之中就会出现重复代码,而通过分析也可以发现,从现实生活来讲,学生本来就属于人,但是学生所表示的范围要比人表示的范围更小,也更加的具。所以要想解决类似的问题,就只能依靠继承的概念来完成了
继承的实现
继承性严格来讲就是指扩充一个类已有的功能,可以使用如下的语法完成
Ø class 子类 extends 父类{}
对于以上格式有以下几点说明:
Ø 对于extends而言,应该翻译为扩充,但是为了理解方便,统一称为继承;
Ø 子类又被称为派生类;
Ø 父类又被称为超类(Super Class)。
继承的基本实现
class Person {
private String name;
private int age;
// setter、getter略
}
class Student extends Person { // Student类继承了Person类
// 此类没有定义任何的操作方法
}
public class TestDemo {
public static void main(String args[]) {
Student stu = new Student(); // 实例化的是子类
stu.setName("张三"); // Person类定义
stu.setAge(20); // Person类定义
System.out.println("姓名:" + stu.getName() + ",年龄:" + stu.getAge());
}
}
程序运行结果:姓名:张三,年龄:19
子类也可以扩总自己的方法
class Person {
private String name;
private int age;
// setter、getter略
}
class Student extends Person { // Student类继承了Person类
private String school ; // 子类扩充的属性
// setter、getter略
}
public class TestDemo {
public static void main(String args[]) {
Student stu = new Student(); // 实例化的是子类
stu.setName("张三"); // Person类定义
stu.setAge(20); // Person类定义
stu.setSchool("清华大学") ; // Student类扩充方法
System.out.println("姓名:" + stu.getName() + ",年龄:" + stu.getAge()
+ ",学校:" + stu.getSchool());
}
}
继承的限制
Ø 限制一:Java不允许多重继承,但是允许多层继承
Ø class A {}
Ø class B {}
Ø class C extends A,B {} // 一个子类继承了两个父类
Ø class A {}
Ø class B extends A {} //B类继承A类
Ø class C extends B {} //C类继承B类
限制二:子类在继承父类的时候严格来讲会继承父类中的全部操作,但是对于所有的私有操作属于隐式继承,而所有的非私有操作属于显式继承。
class A {
private String msg;
public void setMsg(String msg) {
this.msg = msg;
}
public String getMsg() {
return this.msg;
}
}
class B extends A {} // 继承自A类
public class Demo {
public static void main(String args[]) {
B b = new B();
b.setMsg("Hello"); // 设置msg属性,属性通过A类继承
System.out.println(b.getMsg()); // 通过子类对象取得msg属性
System.out.println(msg); //错误
}
}
私有的属性只能通过父类的函数引用,但是不能直接使用
限制三:在子类对象构造之前一定会默认调用父类的构造(默认使用无参构造),以保证父类的对象先实例化,而后再实例化子类对象。
class A {
public A() { // 父类提供的无参构造方法
System.out.println("A、A类的构造方法!");
}
}
class B extends A { // B是子类继承父类A
public B() { // 定义子类的构造方法
System.out.println("B、B类的构造方法!");
}
}
public class Demo {
public static void main(String args[]) { new B(); // 实例化子类对象
}
}
程序执行结果:
A、A类的构造方法!
B、B类的构造方法!
特别注意:super()此语句在子类的首行
当父类中有无参数构造方法是,super()加不加都没有区别,因为他默认会生生成一个super(),但是父类没有无参数构造方法时,就必须使用super(参数)调用父类有参数构造方法