面向对象–继承
继承
继承的由来
在面向对象中多个类存在相同的属性和行为时,我们可以把相同的属性和行为提取出来成为一个
类。那么多个类无需在定义相同的属性和行为。只需要和体取出来的类构成某种关系。就是继承。
其中多个类称为子类(派生类),提取出来的类称为父类(超类)。子类继承父类,子类拥有父类的属性和行为。
继承的好处
- 提高代码的复用性,减小代码量
- 提高代码的扩展性
- 提高代码效率
- 让类与类之间产生关系,为多态提高条件
继承的格式
使用extends关键字表示子类父类之间的继承关系
//父类
public class 父类名 {
...
}
//子类
public class 子类名 extends 父类名 {
...
}
举例:
//父类
public class Animal {
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;
}
public Animal() {
super();
}
public Animal(String name, int age) {
super();
this.name = name;
this.age = age;
}
public void eat(String something) {
System.out.println("吃" + something);
}
}
//子类
public class Cat extends Animal {
public Cat() {
super();
}
public Cat(String name, int age) {
super(name, age);
}
public void eat(String something) {
System.out.println(getAge() + "岁的小猫" + getName() + "正在吃"
+something);
}
}
继承的特点
-
成员变量
-
私有化
虽然子类继承了父类。拥有父类的属性和行为,但是还是不可以直接对私有化的成员变量进行访问,必须通过set/get方法进行访问
-
成员变量相同
当子类的成员变量和父类的成员变量相同时,可以使用super.成员变量访问父类的成员变量。
-
成员变量不相同
成员变量不相同时,不影响
-
-
成员方法
方法名相同—重写
方法的重写:发生在子类和父类继承关系间,返回值类型,方法名, 参数列表都相同。
方法重写注意事项:
- 方法名必须相同,参数类型也必须相同。
- 子类的返回类型必须小于等于父类的返回类型
- 子类的权限修饰符必须大于等于父类的权限修饰符
- 子类不能重写父类中声明为private权限的方法
- 子类重写后抛出的异常不能大于父类中被重写方法的异常
方法名不同
方法名不同时,不影响。
-
构造方法
在子类的构造方法中,如果自己不提供父类构造方法,jvm自动提供一个父类的无参构造方法。
super和this
super表示父类存储空间标识
this表示当前对象的引用
super可以访问父类中的属性。
super可以调用父类中定义的方法。
super可以在子类构造器中调用父类构造器。
继承注意事项
-
Java只支持单继承。
-
可以多层继承
-
子类和父类只是一种相对的。
权限修饰符
public | protected | 缺省(xing) | private | |
---|---|---|---|---|
同一个类中 | YES | YES | YES | YES |
同一个包 | YES | YES | YES | NO |
不同包继承类 | YES | YES | NO | NO |
不同包的无关类 | YES | NO | NO | NO |
抽象类
父类中的方法,被它的子类们重写,子类各自的实现都不尽相同。那么父类的方法声明和方法主体,只有声明还有意义,而方法主体则没有存在的意义了。我们把没有方法主体的方法称为抽象方法。Java语法规定,包含抽象方法的类就是抽象类。
声明抽象类的原因:
- 通过继承关系可知,父类是抽取了多个子类相同的属性和行为的类,理论上不能被实例化。
- 在子类过多时,父类的方法在子类中会忘记重写。
- 父类的方法在子类中需要被重写,那么父类的方法的方法体就变得无意义。
抽象类定义:
使用abstract修饰的类
抽象方法定义:
没有方法体的方法,使用abstract修饰。
抽象类,抽象方法格式:
public abstract class 类名() {
public abstract 返回值类型 方法名(参数列表);
}
格式举例:
//抽象类
public abstract class Animal {
private String color;
private int age;
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Animal(String color, int age) {
super();
this.color = color;
this.age = age;
}
public Animal() {
super();
}
//抽象方法
public abstract void eat(String something);
}
抽象类注意事项
- 抽象类不能被实例化。
- 抽象类被子类继承后,抽象类中的所有的抽象方法都必须被子类重写。除非子类是抽象类。
- 抽象类中有构造方法,用于初始化父类对象。
- 抽象类中不一定有抽象方法,但是有抽象方法的类一定是抽象类