面向对象的第二大特点:继承。它的作用是在已有的基础上继续进行功能的扩充。
定义两个类:人、学生
范例:
代码
class Person {
private String name;
private int age;
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge(){
return this.age;
}
}
class Student {
private String name;
private int age;
private String school;
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge(){
return this.age;
}
public void setSchool(String school){
this.school = school;
}
public String getSchool(){
return this.school;
}
}
以上的开发模式就是简单Java类,发现有重复代码。代码上虽然重复,概念上讲学生一定是人并且学生更加具体。学生的范围更小,具备的属性更多,方法也更多,所以学生应该是人的扩充,要想消除结构定义上的重复,就要使用继承。
在Java中继承使用extends关键字来实现,其定义语法如下:
范例:继承的基本实现
代码
class Person {
private String name;
private int age;
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge(){
return this.age;
}
}
class Student extends Person{ // 定义了一个子类
}
public class TestDemo {
public static void main( String[] args ) {
Student stu = new Student(); // 实例化子类
stu.setName("Oliver");
stu.setAge(25);
System.out.println("name = " + stu.getName() + ", age = " + stu.getAge());
}
} // 输出:name = Oliver, age = 25
当发生类继承关系后,子类可以继承父类的操作,可以实现代码重用,并且子类最低也维持和父类相同的功能。子类可以进行功能扩充,例如:扩充属性和方法。
范例:子类进行功能扩充
代码
class Person {
private String name;
private int age;
public void setName(String name){
this.name = name;
}
public void setAge(int age){
this.age = age;
}
public String getName() {
return this.name;
}
public int getAge(){
return this.age;
}
}
class Student extends Person{ // 定义了一个子类
}
public class TestDemo {
public static void main( String[] args ) {
Student stu = new Student(); // 实例化子类
stu.setName("Oliver");
stu.setAge(25);
stu.setSchool("NWAFU");
System.out.println("name = " + stu.getName() + ", age = " + stu.getAge() + ", school = " + stu.getSchool());
}
}
// 输出:name = Oliver, age = 25, school = NWAFU
继承可以进行父类功能的扩充,可以重用父类中定义的方法。
限制:
1. 子类对象在进行实例化前一定会首先是实例化父类对象,默认调用父类的构造方法后,在调用子类的构造方法进行子类对象实例化。
代码
class Person {
public Person(){
System.out.println("***Person类对象创建***");
}
}
class Student extends Person{ // 定义了一个子类
public Student() {
System.out.println("***Student类对象创建***");
}
}
public class TestDemo {
public static void main( String[] args ){
new Student(); // 进行子类对象实例化
}
}
输出结果:
***Person类对象创建***
***Student类对象创建***
发现没有一条语句明确调用父类构造,但是父类构造依然被执行,证明子类对象的实例化一定会实例化其父类对象。
这时在子类的构造方法中相当于隐含了一个语句“super()”,要进行构造方法调用,就一定要写在构造方法前。此语句在父类有无参构造写与不写一样。如果父类中没有无参构造,就必须使用super()明确指明要调用的父类构造方法。
代码
class Person {
public Person(String name,int age){
System.out.println("***Person类对象创建***");
}
}
class Student extends Person{ // 定义了一个子类
public Student(String name,int age,String school) {
super (name,age); // 明确定义要调用的父类构造
System.out.println("***Student类对象创建***");
}
}
public class TestDemo {
public static void main( String[] args ){
new Student("Oli",25,"NWAFU"); // 进行子类对象实例化
}
}
输出结果:
***Person类对象创建***
***Student类对象创建***
代码
class A{}
class B{}
class C extends A,B{}
这是C类要同时继承A类和B类的操作,可以采用多层继承的形式完成。
代码
class A{}
class B extends A{}
class C extends B{}
最多三层继承。
Java不允许多重继承但允许多层继承。
3. 在进行继承时,子类会继承父类的所有结构。所有的非私有操作属于显示继承(直接调用),所有私有操作属于隐式继承(通过其他形式调用,例如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 class TestDemo {
public static void main( String[] args ){
Student stu = new Student();
stu.setName("Jack");
System.out.println(stu.getName());
}
} // Jack
代码
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(name);
// 编译错误,私有不能访问
System.out.println(getName());
}
}
public class TestDemo {
public static void main( String[] args ){
Student stu = new Student();
stu.setName("Jack");
System.out.println(stu.getName());
stu.fun();
}
}
输出结果
Jack
Jack
此时中的属性的确被子类继承,但子类能够使用的只是所有的非private操作,所有私有操作无法直接使用,所以称为隐式继承。
1.继承的语法以及继承的目的(扩展已有类功能,使代码重用);
2.子类对象的实例化操作流程:一定要先实例化父类对象,而后在实例化子类对象;
3.继承的限制:不允许多重继承,只允许多层继承。