继承的概念
继承是面向对象最显著的一个特性。继承是从已有的类中派生出新的类,新的类能吸收已有类的数据属性和行为,并能扩展新的能力。
继承就是子类继承父类的特征和行为,使得子类对象(实例)具有父类(非私有)的实例域和方法,或子类从父类继承方法,使得子类具有父类相同的行为。
如
继承的格式
继承关键字
extends
当一个类没有继承的两个关键字,则默认继承object(祖先类)。
public class 父类 {
}
public class 子类 extends 父类 {
}
为什么要用继承
学生类
public class Student {
private String name;
private int id;
public Student(String name, int id) {
this.name = name;
this.id = id;
}
public void eat(){
System.out.println(name+"正在吃");
}
public void sleep(){
System.out.println(name+"正在睡");
}
public void introduction() {
System.out.println("大家好!我是" + id + "号" + name + ".");
}
}
教师类
public class Teacher {
private String name;
private int id;
public Teacher(String name, int id) {
this.name = name;
this.id = id;
}
public void eat(){
System.out.println(name+"正在吃");
}
public void sleep(){
System.out.println(name+"正在睡");
}
public void introduction() {
System.out.println("大家好!我是" + id + "号" + name + ".");
}
}
从这两段代码可以看出来,代码存在重复了,导致后果就是代码量大且臃肿,而且维护性不高(维护性主要是后期需要修改的时候,就需要修改很多的代码,容易出错),所以要从根本上解决这两段代码的问题,就需要继承,将两段代码中相同的部分提取出来组成 一个父类:
public class People {
private String name;
private int id;
public People(String name, int id) {
this.name = name;
this.id = id;
}
public void eat(){
System.out.println(name+"正在吃");
}
public void sleep(){
System.out.println(name+"正在睡");
}
public void introduction() {
System.out.println("大家好!我是" + id + "号" + name + ".");
}
}
这个People类就可以作为一个父
public class Teacher extends People {
public Teacher(String name, int id) {
super(name, id);
}
}
然后学生类和教师类继承这个类之后,就具有父类当中的属性和方法,子类就不会存在重复的代码,维护性也提高,代码也更加简洁,提高代码的复用性(复用性主要是可以多次使用,不用再多次写同样的代码) 继承之后的代码:
学生类:
public class Student extends People{
public Student(String name, int id) {
super(name, id);
}
}
教师类:
public class Teacher extends People {
public Teacher(String name, int id) {
super(name, id);
}
}
继承的特性
1.java中一个子类只能够继承一个父类,一个父类可以被多个子类继承,可以多层继承(一个孩子只能有一个亲生父亲,一个父亲可以有多个孩子,父亲上面还有父亲)。
2.子类拥有父类非 private 的属性、方法。(可以通过setter、getter方法间接的进行操作)。
3.子类可以对父类进行扩展,子类可以用自己的方式实现父类的方法(重写)。
4.在继承关系之中,如果要实例化子类对象,会默认先调用父类构造,为父类之中的属性初始化,之后再调用子类构造,为子类之中的属性初始化,即:默认情况下,子类会找到父类之中的无参构造方法。
public class People {
private String name;
private int id;
public People() {
System.out.println("父类无参构造");
}
}
public class Student extends People{
void eat(){
System.out.println("吃饭");
}
public static void main(String[] args) {
Student student = new Student();
student.eat();
}
}
继承关系中构造方法的执行先后顺序
父类静态代码 >子类静态代码 >父类构造方法 >子类构造方法
5.提高了类之间的耦合性(继承的缺点,耦合度高就会造成代码之间的联系越紧密,代码独立性越差)。
super 与 this 关键字
super关键字:我们可以通过super关键字来实现对父类成员的访问,用来引用当前对象的父类。
this关键字:指向自己的引用。
public class People {
int id=10;
}
public class Student extends People{
int id=20;
void show(){
int id=30;
System.out.println(id);
System.out.println(this.id);
System.out.println(super.id);
}
}
public class Test {
public static void main(String[] args) {
Student student = new Student();
student.show();
}
}
方法重写
当父类继承下来的方法不满足子类需要的时候,可以写一个和父类声明一样的方法,方法体中逻辑重新实现,这个子类重新定义的方法就是重写后的方法。重写后的方法会覆盖父类的功能,因此成为方法重写,方法的覆盖。如:一个动物类的eat方法猫继承之后要吃鱼,而狗要吃骨头,因此要对eat方法重写。
public class Animal {
void eat(){
}
}
public class Cat extends Animal{
@Override
void eat() {
System.out.println("猫吃鱼");
}
}
public class Cat extends Animal{
@Override
void eat() {
System.out.println("猫吃鱼");
}
}