
继承--顾名思义,承接上一辈的,继续扩大发展,因此,当你的子类没有拓展或改变父类的功能,是没必要继承的,关键字extends
需要继承的类被称为子类/派生类,被继承的类成为父类/基类/超类,继承就是对所有子类中共性的抽取,从而放入一个父类,需要时可以直接调用父类的成员变量和方法
class Student extends Person{
public void study() {
System.out.println(this.name + " 正在学习!!!");
}
}
class Teacher extends Person{
public void teach() {
System.out.println(this.name + " 正在授课!!!");
}
}
public class Person {
public String name;
public int age;
public void speak() {
System.out.println(this.name + " 正在说话");
}
}
class Test {
public static void main(String[] args) {
Student student = new Student();
student.name = "小玉";
student.speak();
Teacher teacher = new Teacher();
teacher.name = "严老师";
teacher.speak();
}
}
(1)
当父类与子类成员变量名一致时,this调用的是子类自己的成员变量,就近原则
public class Person {
public String name;
public int age = 10;
public void speak() {
System.out.println(this.name + " 正在说话");
}
}
class Teacher extends Person{
public int age = 11;
public void teach() {
System.out.println(this.name + " 正在授课!!!");
}
public void fac() {
System.out.println(this.age);
}
}
(2)
如果在子类方法中非要调用父类的同名成员变量,则应引用super关键字
class Teacher extends Person{
public int age = 11;
public void teach() {
System.out.println(this.name + " 正在授课!!!");
}
public void fac() {
System.out.println("子类的年龄: " + this.age);
System.out.println("子类的年龄: " + super.age);
}
}
(3)
当父类中没有构造方法时或者只有无参数的构造方法时,子类的构造方法会默认用super关键字调用父类无参数的构造方法
public class Person {
public String name;
public int age = 10;
public Person() {
System.out.println("父类的无参数构造方法!!!");
}
public void speak() {
System.out.println(this.name + " 正在说话");
}
}
class Teacher extends Person{
public void teach() {
System.out.println(this.name + " 正在授课!!!");
}
}
class Test {
public static void main(String[] args) {
Student student = new Student();
student.name = "小玉";
(4)
而当父类只有带参数的构造方法时,必须手动在子类构造方法第一行加上super对应的参数构造方法
public class Person {
public String name;
public int age = 10;
public Person(String name, int age) {
System.out.println("父类的含有参数构造方法!!!");
}
public void speak() {
System.out.println(this.name + " 正在说话");
}
}
class Teacher extends Person{
public Teacher(String name, int age) {
super(name,age);
}
public void teach() {
System.out.println(this.name + " 正在授课!!!");
}
}
final意为"最终的",被final修饰的最终类不能被继承
1.代码:
final class Person{
public String name;
public int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}2.图片

private在类与对象中详细解释过,意为"私有的",只能在当前类使用,所以即使子类继承了父类所有的属性,但是私有属性仍没有办法使用
1.代码
class Person{
public String name;
public int age;
private int tall;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
class Student extends Person{
public Student(String name, int age) {
super(name,age);
super.tall = 10;
super.name = "小明";
}
}2.图片

我么们知道,this代表当前类,super代表父类,都能调用构造方法,和成员变量,那么有什么相同点和区别呢? 请看下表: this与super的比较 thissuperthis调用构造方法时,必须写在第一行super调用父类构造方法时,必须写在第一行不可以在普通成员方法中使用this调用构造方法不可以在子类普通成员方法中使用super调用父类构造方法this()可调用当前类不带参数的构造方法,得手动添加,不写的时候不会默认调用super()可调用父类不带参数构造方法,不写的时候子类当中默认调用当前类中构造方法可以不相互调用子类中必须调用父类的构造方法,并且当父类只有带参数的构造方法时,子类的所有构造方法必须手动添加使用super(x,y,...)来调用父类的构造方法,以此来给父类成员变量初始化this可调用当前类的成员方法与成员变量super可调用父类的成员方法与成员变量this+点号引用当前类成员变量与方法只能在非静态方法中使用super+点号引用父类的成员变量与方法只能在非静态方法中使用this不能调用当前类静态成员方法super不能调用父类静态成员方法this是当前对象的引用super可以理解为子类从父类继承下来的引用
在上一篇类与对象当中,我们学习了不同代码块的执行速度,即静态代码块执行速度 > 实例代码块执行速度 > 构造方法执行速度,
那么,在父类与子类中都存在这三个时,执行顺序又是什么呢?
1.代码
/**
* Created with IntelliJ IDEA.
* Description:
* User: 32309
* Date: 2025-06-06
* Time: 22:42
*/
class Person{
public String name;
public int age;
private int tall;
public Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("父类构造方法!!!");
}
static {
System.out.println("父类静态代码块!!!");
}
{
System.out.println("父类实例代码块!!!");
}
}
class Student extends Person{
public Student(String name, int age) {
super(name,age);
super.name = "小明";
System.out.println("子类构造方法!!!");
}
static {
System.out.println("子类静态代码块!!!");
}
{
System.out.println("子类实例代码块!!!");
}
}
public class Test {
public static void main(String[] args) {
Student student = new Student("1",10);
}
}2.图片

3.分析
当实例化子类时,父类与子类的静态代码块在加载过程中先被执行,然后子类的构造方法调用super调用父类的构造方法,初始化父类成员变量,父类的实例代码块与构造方法先后执行,接着是子类的实例代码块与构造方法先后执行

多态是不同生物对同一种行为的不同表现形式,比如,有的人难受的时候会偷偷哭一场来释放自己的情绪,有的人则会选择吃甜品来缓解心情,更有的人会憋在心里慢慢消化... 正所谓对一本书的解读,一千个读者有一千个哈姆雷特,等等种种表明,万物多态构成了形形色色的世界,而Java当中也正是利用多态来实现丰富的动作
1. 必须实现继承 2. 通过父类的引用调用重写的方法 3. 子类必须要重写父类的方法 4.实现向上或向下转型
向上转型是动态绑定的一种,即将子类对象赋给父类,父类引用变量引用的是子类的对象,该父类引用变量调用不了子类特有的方法,向上转型有三种形式: 1.直接赋值 2.将父类类型作为参数 3.将父类类型作为返回值
1.直接将子类对象赋值给父类类型的引用
2.代码及效果图:
/**
* Created with IntelliJ IDEA.
* Description:
* User: 32309
* Date: 2025-06-06
* Time: 22:42
*/
class Person{
public String name;
public int age;
public void resolveSad() {
}
}
class Girl1 extends Person {
public Girl1(String name) {
this.name = name;
}
public void resolveSad() {
System.out.println(this.name + " 通过吃甜甜的奶糖来缓解悲伤");
}
}
class Girl2 extends Person {
public Girl2(String name) {
this.name = name;
}
public void resolveSad() {
System.out.println(this.name + " 攥紧拳头默默忍受慢慢消化悲伤");
}
}
public class Test {
public static void fib(Person person) {
person.resolveSad();
}
public static void main(String[] args) {
Person person1 = new Girl1("小樱");
Person person2 = new Girl2("小洛");
person1.resolveSad();
person2.resolveSad();
}
}
1.在测试类中,将子类对象对位参数传递,将父类对象作为形式参数接受
2.代码及效果图:
/**
* Created with IntelliJ IDEA.
* Description:
* User: 32309
* Date: 2025-06-06
* Time: 22:42
*/
class Person{
public String name;
public int age;
public void resolveSad() {
}
}
class Girl1 extends Person {
public Girl1(String name) {
this.name = name;
}
public void resolveSad() {
System.out.println(this.name + " 通过吃甜甜的奶糖来缓解悲伤");
}
}
class Girl2 extends Person {
public Girl2(String name) {
this.name = name;
}
public void resolveSad() {
System.out.println(this.name + " 攥紧拳头默默忍受慢慢消化悲伤");
}
}
public class Test {
public static void fib(Person person) {
person.resolveSad();
}
public static void main(String[] args) {
fib(new Girl1("小樱"));
fib(new Girl2("小美"));
}
}
1.在一个方法中,满足条件return一个子类给父类
2.代码及效果图:
import java.util.Scanner;
/**
* Created with IntelliJ IDEA.
* Description:
* User: 32309
* Date: 2025-06-06
* Time: 22:42
*/
class Person{
public String name;
public int age;
public void resolveSad() {
}
}
class Girl1 extends Person {
public Girl1(String name) {
this.name = name;
}
public void resolveSad() {
System.out.println(this.name + " 通过吃甜甜的奶糖来缓解悲伤");
}
}
class Girl2 extends Person {
public Girl2(String name) {
this.name = name;
}
public void resolveSad() {
System.out.println(this.name + " 攥紧拳头默默忍受慢慢消化悲伤");
}
}
public class Test {
public static Person fib(int num) {
if (num == 1) {
return new Girl1("小樱");
} else {
return new Girl2("小洛");
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
while (scanner.hasNextInt()) {
int num = scanner.nextInt();
Person person = fib(num);
person.resolveSad();
}
}
}
向下转型也是动态绑定的一种,指的是将父类对象强制转化为子类类型的引用,强制转换后
子类引用可调用该子类特有的方法
import java.util.Scanner;
/**
* Created with IntelliJ IDEA.
* Description:
* User: 32309
* Date: 2025-06-06
* Time: 22:42
*/
class Person{
public String name;
public int age;
public void resolveSad() {
}
}
class Girl1 extends Person {
public Girl1(String name) {
this.name = name;
}
public void resolveSad() {
System.out.println(this.name + " 通过吃甜甜的奶糖来缓解悲伤");
}
public void eatCandy() {
System.out.println(this.name + " 爱吃奶糖");
}
}
class Girl2 extends Person {
public Girl2(String name) {
this.name = name;
}
public void walk() {
System.out.println(this.name + " 正在散步");
}
public void resolveSad() {
System.out.println(this.name + " 攥紧拳头默默忍受慢慢消化悲伤");
}
}
public class Test {
public static void main(String[] args) {
Person person = new Girl1("小樱");
Girl1 girl1 = (Girl1) person;
girl1.resolveSad();
}
}
向下转型的强制转换存在风险,不能同时转换两个不同子类对象,意为每个人都有自己独特的行为方式与属性
1.代码及效果图:
Person person = new Girl1("小樱");
Girl1 girl1 = (Girl1) person;
girl1.resolveSad();
Girl2 girl2 = (Girl2) person;
girl2.walk();
2.ClassCastException
我们可以发现当同时强制转换两个对象会爆ClassCastException异常,这是类型转换异常,所以说类型转换存在风险
静态绑定是指在编译阶段发生的多态,典型的就是重载

当在父类中所实现的方法不满足于子类的需求时,那么这就需要重写,而重写则就是动态绑定发生的先决条件
1.当子类继承父类时,可以选择重写对应相同的方法 2.当子类重写抽象类,需要重写抽象类中所有的抽象方法 3.当一个类实现接口时,需要重写接口当中所有方法(抽象类与接口在下一篇博客会讲解)
1.重写的方法返回值必须相同 (子类继承父类时,返回值构成父子关系也可以) 2.重写的方法参数列表必须相同 如参数个数,参数类型,顺序都要一致

3.子类重写方法的权限必须大于等于父类的权限
1.static

2.private

3.final

重写 | 重载 |
|---|---|
重写方法的返回值类型,参数列表必须相同 | 重载方法的返回值类型不做要求,参数列表的参数个数,参数类型,顺序必须有一个不同 |
子类重写的方法权限必须大于等于父类方法 | 重载方法权限不做要求 |
被static,private,final修饰的方法不能重写 | 被任何修饰符修饰都能重载 |
abstract修饰的抽象方法必须被重写 | 没有必须被重载的方法 |
重写时发生动态绑定的基础 | 重载时发生静态绑定的基础 |