封装 | 继承 | 多态 |
对象代表什么,就得封装对应的数据,并提供数据对应的行为 | 当类与类之间,存在相同(共性)内容,并满足子类是父类中的一种,就可以考虑使用继承,来优化代码 |
Java中提供一个关键字extends,用这个关键字,我们可以让一个类和另一个类建立起继承关系 |
eg: public class Student extends Person { } |
可以把多个子类中重复的代码抽取到父类中,提高代码的复用性 |
子类可以在父类的基础上,增加其他的功能,使子类更加强大 |
//一个继承体系
public class Test {
public static void main(String[] args) {
Husky h = new Husky();
h.eat();// 哈士奇在吃骨头!
h.drink();// 动物在喝水!
h.LookHouse();// 狗在看家!
BoSiMao bs = new BoSiMao();
bs.eat();// 波斯猫在吃鲫鱼!
bs.drink();// 动物在喝水!
bs.CatchMouse();// 猫在抓老鼠!
}
}
//动物
class Animal {
public void eat() {
System.out.println("动物在吃饭!");
}
public void drink() {
System.out.println("动物在喝水!");
}
}
//狗
class Dog extends Animal {
public void LookHouse() {
System.out.println("狗在看家!");
}
}
//猫
class Cat extends Animal {
public void CatchMouse() {
System.out.println("猫在抓老鼠!");
}
}
//哈士奇
class Husky extends Dog {
@Override
public void eat() {
System.out.println("哈士奇在吃骨头!");
}
}
//波斯猫
class BoSiMao extends Cat {
@Override
public void eat() {
System.out.println("波斯猫在吃鲫鱼!");
}
}
构造方法 | 非私有 不能 | private 不能 |
成员变量 | 非私有 能 | private 能(能继承下来但不能直接调用) |
成员方法 | 非私有 能(只有父类中的虚方法才能被子类继承) | private 不能 |
继承中:成员变量的访问特点 | 直接调用: 就近原则 this调用: 从本类成员位置开始往上找 super调用: 直接访问父类 |
继承中:成员方法的访问特点 | 直接调用: 就近原则 super调用: 直接访问父类 |
继承中:构造方法的访问特点 | 父类中的构造方法不会被子类继承 子类中所有的构造方法默认先访问父类中的无参构造,再执行自己 |
//成员变量访问特点
public class Test1 {
public static void main(String[] args) {
Zi z = new Zi();
z.show();
}
}
//父类
class Fu {
String name = "父";
}
//子类
class Zi extends Fu {
String name = "大子";
public void show() {
String name = "小子";
System.out.println(name);//打印结果: 小子
System.out.println(this.name);//打印结果: 大子
System.out.println(super.name);//打印结果: 父
}
}
//成员方法访问特点
public class Test2 {
public static void main(String[] args) {
Student s1 = new Student();
s1.lunch();
}
}
//父类
class Person {
public void eat() {
System.out.println("吃米饭!");
}
public void drink() {
System.out.println("喝热水!");
}
}
//子类
class Student extends Person {
public void lunch() {
this.eat();//打印结果: 吃牛排!
this.drink();//打印结果: 喝冷水!
super.eat();//打印结果: 吃米饭!
super.drink();//打印结果: 喝热水!
}
//方法的重写
@Override
public void eat() {
System.out.println("吃牛排!");
}
@Override
public void drink() {
System.out.println("喝冷水!");
}
}
书写格式 | 在继承体系中,子类出现了和父类中一模一样的方法声明,我们称子类这个方法是重写的方法 |
@Override重写注解 | 放在重写方法的上面,校验子类重写时语法是否正确 |
方法重写的本质 | 子类覆盖了从父类中继承下来虚方法表中的方法 |
//构造方法访问特点: 子类中所有的构造方法默认先访问父类中的无参构造,再执行自己
//为什么?
//因为,子类在初始化的时候,可能会使用到父类中的数据,如果父类没有初始化,子类将无法使用其数据
//所以,子类初始化之前,一定要调用父类构造方法先完成父类数据空间的初始化
//怎么调用父类构造方法的?
//1.子类构造方法的第一行语句默认都是: super(); 不写也存在,且必须在第一行
//2.如果想要调用父类有参构造,必须手动书写super进行调用
public class Test3 {
public static void main(String[] args) {
Student s1 = new Student();//运行结果: 父类的无参构造!
// 子类的无参构造!
Student s2 = new Student("彭于晏", 18);
System.out.println(s2.name + " " + s2.age);//打印结果: 彭于晏 18
}
}
//父类
class Person {
String name;
int age;
//无参构造
public Person() {
System.out.println("父类的无参构造!");
}
//有参构造
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
//子类
class Student extends Person {
//无参构造
public Student() {
//子类构造方法中隐藏的super()去访问父类的无参构造
super();
System.out.println("子类的无参构造!");
}
//有参构造
public Student(String name, int age) {
//手动书写super去访问父类的有参构造
super(name, age);
}
}
关键字 | 理解 | 访问成员变量 | 访问成员方法 | 访问构造方法 |
---|---|---|---|---|
this | 理解为一个变量,表示当前方法调用者的地址值 | this.成员变量 访问本类成员变量 | this.成员方法(...) 访问本类成员方法 | this(...) 访问本类中的其他构造方法 |
super | 代表父类存储空间 | super.成员变量 访问父类成员变量 | super.成员方法(...) 访问父类成员方法 | super(...) 访问父类构造方法 |
public class Test4 {
public static void main(String[] args) {
Student s = new Student();
System.out.println(s.name + " " + s.age + " " + s.school);
//打印结果: null 0 西南民族大学
}
}
class Student {
String name;
int age;
String school;
//需求: 学校默认为西南民族大学
//空参构造
public Student() {
//这里是用this去调用本类中的其他构造
this(null, 0, "西南民族大学");
}
//有参构造
public Student(String name, int age, String school) {
this.name = name;
this.age = age;
this.school = school;
}
}