该文章Github地址:https://github.com/AntonyCheng/java-notes【有条件的情况下推荐直接访问GitHub以获取最新的代码更新】
在此介绍一下作者开源的SpringBoot项目初始化模板(Github仓库地址:https://github.com/AntonyCheng/spring-boot-init-template【有条件的情况下推荐直接访问GitHub以获取最新的代码更新】& CSDN文章地址:https://blog.csdn.net/AntonyCheng/article/details/136555245),该模板集成了最常见的开发组件,同时基于修改配置文件实现组件的装载,除了这些,模板中还有非常丰富的整合示例,同时单体架构也非常适合SpringBoot框架入门,如果觉得有意义或者有帮助,欢迎Star & Issues & PR!
上一章:由浅到深认识Java语言(12):代码块&静态
22.继承(面向对象第二大特性)
定义以及实例
Java 中的继承通过子类继承父类,那么子类就能获得父类中所有的结构,包括父类的属性和方法;
当子类继承父类之后,子类可以定义自己的结构,因此子类是父类的一种扩展,而不是子集;
继承的目的:
快速地创建出一个类;
基本格式:extends关键字
//有一个父类是 class Person
//有一个子类是 class Teacher
public class Teacher extends Person{
}
示例如下:
类:grandfather 类、father 类、son 类,做一个一家三代信息获取器;
grandfather 类:
package top.sharehome.BagOne;
public class grandfather {
String grandfatherName;
int grandfatherAge;
char grandfatherSex;
public String getGrandfatherName() {
return grandfatherName;
}
public void setGrandfatherName(String grandfatherName) {
this.grandfatherName = grandfatherName;
}
public int getGrandfatherAge() {
return grandfatherAge;
}
public void setGrandfatherAge(int grandfatherAge) {
this.grandfatherAge = grandfatherAge;
}
public char getGrandfatherSex() {
return grandfatherSex;
}
public void setGrandfatherSex(char grandfatherSex) {
this.grandfatherSex = grandfatherSex;
}
}
father 类:
package top.sharehome.BagOne;
public class father extends grandfather{
String fatherName;
int fatherAge;
char fatherSex;
public String getFatherName() {
return fatherName;
}
public void setFatherName(String fatherName) {
this.fatherName = fatherName;
}
public int getFatherAge() {
return fatherAge;
}
public void setFatherAge(int fatherAge) {
this.fatherAge = fatherAge;
}
public char getFatherSex() {
return fatherSex;
}
public void setFatherSex(char fatherSex) {
this.fatherSex = fatherSex;
}
}
son 类:
package top.sharehome.BagOne;
public class son extends father {
String sonName;
int sonAge;
char sonSex;
public String getSonName() {
return sonName;
}
public void setSonName(String sonName) {
this.sonName = sonName;
}
public int getSonAge() {
return sonAge;
}
public void setSonAge(int sonAge) {
this.sonAge = sonAge;
}
public char getSonSex() {
return sonSex;
}
public void setSonSex(char sonSex) {
this.sonSex = sonSex;
}
public son() {
}
}
demo 类:
package top.sharehome.BagOne;
public class demo {
public static void main(String[] args) {
son s = new son(); //只调用了 son 的构造器,就能调用 father 和 grandfather
s.setSonName("陈三");
s.setFatherName("陈二");
s.setGrandfatherName("陈一");
s.setSonAge(9);
s.setFatherAge(33);
s.setGrandfatherAge(60);
s.setSonSex('男');
s.setFatherSex('女');
s.setGrandfatherSex('男');
System.out.println("姓名为"+"\t"+s.getSonName()+"\t"+s.getFatherName()+"\t"+s.getGrandfatherName());
System.out.println("年龄为"+"\t"+s.getSonAge()+"\t"+s.getFatherAge()+"\t"+s.getFatherAge());
System.out.println("性别为"+"\t"+s.getSonSex()+"\t"+s.getFatherSex()+"\t"+s.getGrandfatherSex());
}
}
打印效果如下:
**案例:**公司员工;
- 员工
- 关系
- 程序员
- 人事
- 共有方法:打卡
sign()
- 特有方法
- 程序员:敲代码
- 人事:招聘
- 关系
yuangong 类:
package top.sharehome.BagOne;
public class yuangong {
public void sign() {
System.out.println("打卡!");
}
}
chengxuyuan 类:
package top.sharehome.BagOne;
public class chengxuyuan extends yuangong {
public void daima() {
System.out.println("敲代码!");
}
}
renshi 类:
package top.sharehome.BagOne;
public class renshi extends yuangong {
public void zhaopin() {
System.out.println("招聘!");
}
}
demo 类:
package top.sharehome.BagOne;
public class demo {
public static void main(String[] args) {
renshi r = new renshi();
chengxuyuan c = new chengxuyuan();
r.sign();
r.zhaopin();
c.sign();
c.daima();
}
}
打印效果如下:
子类对象实例化过程(继承的过程)
当创建子类对象时,子类继承链上所有的父类的构造器都会被调用,调用顺序是继承链最顶端依次往下,直到子类自身为止。构造器的作用有两个,一是创建对象,二是构造器的内容被执行,也就是说子类对象中是包含父类的对象;
实例如下:
Creator 类:
package top.sharehome.BagOne;
public class Creator {
private String name;
public Creator() {
System.out.println("Creator()");
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Animal 类:
package top.sharehome.BagOne;
public class Animal extends Creator {
private int age;
public Animal() {
System.out.println("Animal()");
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
Dog 类:
package top.sharehome.BagOne;
public class Dog extends Animal {
private String sex;
public Dog() {
System.out.println("Dong()");
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
}
demo 类:
package top.sharehome.BagOne;
public class demo {
public static void main(String[] args) {
Dog dog = new Dog();
}
}
打印效果如下:
super关键字
超类/父类/基类 == superclass
作用:super 描述的是“父类对象的” <==> this 描述的是“当前对象的”
super修饰构造器
使用 super 修饰构造器,来指定调用父类的一个构造器;
默认情况下,子类的任何一个构造器都需要调用父类空参的构造器,因为子类对象在创建时必然会通过调用父类的构造器来创建父类的对象,这个对象会放在子类对象的内部,此时系统会在每一个构造器中默认提供一个 “super()” 空参;
子类的任何一个构造器也可以调用父类非空参的构造器,此时系统就不会提供一个 “super()” 空参;
注意:一旦父类对象中有构造器但无空参构造器时,子类中每一个构造器都必须加上“super(参数)”
示例如下:
Person 类:
package top.sharehome.BagOne;
public class Person {
String name;
public Person(String name) {
this.name = name;
}
}
Teacher 类:
package top.sharehome.BagOne;
public class Teacher extends Person{
public Teacher() {
super("小红");
System.out.println(name);
System.out.println("这是空参构造器");
}
public Teacher(String name) {
super(name);
System.out.println(name);
System.out.println("这是非空参构造器");
}
}
Demo 类:
package top.sharehome.BagOne;
public class Demo {
public static void main(String[] args) {
Teacher t1 = new Teacher();
Teacher t2 = new Teacher("小陈");
}
}
打印效果如下:
super修饰属性
如果父类和子类对象中有同名属性,通过 super 指明调用父类中的同名属性,
如果父类和子类对象中没有同名属性,super 可以省略;
示例如下:
A 类:
package top.sharehome.BagOne;
public class A {
String id = "2020****0123";
String name = "小陈";
}
B 类:
package top.sharehome.BagOne;
public class B extends A{
String id = "2020****0199";
public void show() {
System.out.println(id);
System.out.println(super.id); //不可省略
System.out.println(name); //可省略
}
}
Demo 类:
package top.sharehome.BagOne;
public class Demo {
public static void main(String[] args) {
B b = new B();
b.show();
}
}
打印效果如下:
super修饰方法
指明调用父类中的某个方法;
**应用场景:**往往出现在父类和子类中有同名方法的情况,这种场景也称为方法的重写;
示例如下:
A 类:
package top.sharehome.BagOne;
public class A {
public void method() {
System.out.println("A method");
}
}
B 类:
package top.sharehome.BagOne;
public class B extends A{
public void method() {
System.out.println("B method");
}
public void getSuperMethod() {
super.method();
}
}
Demo 类:
package top.sharehome.BagOne;
public class Demo {
public static void main(String[] args) {
B b = new B();
b.method();
b.getSuperMethod();
}
}
打印效果如下:
方法的重写(override):
-
概念:
当子类继承父类时,父类的方法对子类不适用,因此子类通过重写父类的方法来实现目的;
也就是在子类中的方法要去覆盖父类中的方法;
-
注意事项:
父类中私有方法不能被重写,但子类可以继承父类的私有方法,只是收到访问权限的限制不能访问;
方法名,参数列表,返回值类型必须相同,返回权限修饰符不能大于父类,最好保持一致;
静态方法不能被重写;
-
示例如下:
Person 类:
package top.sharehome.BagOne; public class Person { String name; int age; public void eat() { System.out.println("吃饭"); } }
Teacher 类:
package top.sharehome.BagOne; public class Teacher extends Person{ public void eat() { System.out.println("老师吃饭"); } }
Demo 类:
package top.sharehome.BagOne; public class Demo { public static void main(String[] args) { Teacher t1 = new Teacher(); t1.eat(); } }
打印效果如下: