继承概述
多个类中存在相同属性和行为是,将这些内容抽取到单独一个类中,那么多个类无需再定义这些属性和行为,只要继承那个类即可。
通过extends关键字可以实现类与类的继承
格式:
class 子类名 extends 父类名 { }
单独的这个类称为父类,基类或超类;这多个类可以称为子类或者派生类。
有了继承以后,我们定义一个类时,可以在一个已经存在的类的基础上,还可以定义自己的新成员
继承的好处
提高了代码的复用性
多个类的相同成员可以放到同一个类中
提高了代码的维护性
如果功能代码需要修改,修改一处即可
让类与类之间产生了关系,是多态的前提
也是继承的一个弊端:类的耦合性很强
开发的原则:低耦合,高内聚。
耦合:类与类的关系
内聚:自己完成某件功能的能力
Java中继承的特点:
Java只支持单继承,不支持多继承。(有些语言支持多继承,格式:extends 类1,类2,....)
Java支持多层继承(继承体系)
class A{}
class B extends A{}
class C extends B{}
(C可以调用B中方法也可以调用A中方法)
继承的注意事项:
子类只能继承父类所有非私有的成员(成员方法和成员变量)
子类不能继承父类的构造方法,但可以通过super关键字去访问父类构造方法
不要为了部分功能而去继承
继承中成员变量的关系
子类中的成员变量和父类中的成员变量名称一样时,变量就近原则。
先查看子类方法的局部范围找,有就使用,否则在子类的成员方法找,有就是用,否则在父类的成员范围找。
super关键字
super的用法和this很像
super代表父类存储空间的标识(可以理解未父类引用)
用法(this和super均可如下使用)
调用成员变量
this.成员变量 调用本类的成员变量
super.成员变量 调用父类的成员变量
调用构造变量
this(...) 调用本类的构造方法
super(...) 调用父类的构造方法
调用成员方法
this.成员方法 调用本类的成员方法
super.成员方法 调用父类的成员方法
继承中构造方法的关系
子类中所有的构造方法默认都会访问父类中空参数的构造方法
因为子类会继承父类中的数据,可能还会使用父类的数据,所以子类初始化之前,一定要先完成父类数据初始化
注意:子类每一个构造方法的第一条语句默认都是super();
如果父类中没有无参构造方法,默认不会对父类成员变量进行初始化,解决方案:
1、在父类中加一个无参构造方法
2、通过使用super关键字去显示的调用父类的带参构造方法
3、子类通过使用this去调用本类的其他构造方法
子类一定要有一个去访问了父类的构造方法,否则父类数据就没有初始化
注意事项:
this(...)或super(...)必须出现在第一条语句上。
如果不是放在了第一条语句上,就可能对父类的数据进行了多次初始化
一个类的静态代码块,构造代码块,构造方法的执行流程
静态代码块>构造代码块>构造方法
静态的内容是随着类的加载而加载
静态代码块的内容会优先执行
子类初始化之前先会进行父类的初始化
一个类的初始化过程
成员变量进行初始化
默认初始化
显示初始化
构造方法初始化
继承中成员方法的关系
如果子类中的方法和父类中的方法声明一样,通过子类调用方法,先找子类中看有没有这个方法,有就使用;没有再看父类中。(方法重写)
方法重写:子类中出现了和父类中方法一模一样(方法名、参数列表、返回值类型)的方法。也被称为方法覆盖、方法复写。
使用特点:
如果方法名不同,就调用对应方法
如果方法名相同,最终使用的是子类自己的
方法重写的应用:
当子类需要父类的功能,而功能主体子类有自己特有内容时,可以重写父类中的方法,这样即沿袭了父类的功能,又定义了子类特有的内容。
方法重写的注意事项
父类中私有方法不能被重写 (父类私有方法子类无法继承 )
子类重写父类方法时,访问权限不能更低
父类静态方法,子类也必须通过静态方法进行重写。
Override:方法重写
Overload:方法重载
class Person{
private String name;
private int age;
public Person() {
}
public Person(String name,int age) {
this.name=name;
this.age=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 Student2 extends Person{
public Student2() {
}
public Student2(String name,int age) {
super(name,age);
}
}
class Teacher extends Person{
public Teacher() {
}
public Teacher(String name,int age) {
super(name,age);
}
}
public class PersonTest {
public static void main(String[] args) {
Student2 s = new Student2();
s.setName("刘备");
s.setAge(25);
System.out.println(s.getName()+"---"+s.getAge());
Teacher ss = new Teacher("诸葛孔明",30);
System.out.println(ss.getName()+"---"+ss.getAge());
}
}
------------------------------------------------------------------------
结果:
刘备---25
诸葛孔明---30
class Animal{
private String name;
private int age;
private String color;
public Animal() {
}
public Animal(String name,int age, String color) {
this.name=name;
this.age=age;
this.color=color;
}
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 String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public void eat() {
System.out.println("吃!");
}
}
class Cat extends Animal{
public Cat() {
}
public Cat(String name,int age,String color) {
super(name,age,color);
}
public void PlayGame(String name) {
System.out.println(name+"玩游戏!");
}
}
class Dog extends Animal{
public Dog() {
}
public Dog(String name,int age,String color) {
super(name,age,color);
}
public void LookDoor(String name) {
System.out.println(name+"看门!");
}
}
public class CatDogtest {
public static void main(String[] args) {
Cat s = new Cat();
s.setName("花花");
s.setAge(2);
s.setColor("花色");
System.out.println(s.getName()+"---"+s.getAge()+"---"+s.getColor());
s.eat();
s.PlayGame("花花");
System.out.println("--------------");
Dog ss = new Dog("小黑",3,"黑色");
System.out.println(ss.getName()+"---"+ss.getAge()+"---"+ss.getColor());
ss.eat();
ss.LookDoor("小黑");
}
}
-----------------------------------------------------------------------------------------
结果:
花花---2---花色
吃!
花花玩游戏!
--------------
小黑---3---黑色
吃!
小黑看门!